这是一个很基础的教程,高手飘过。
现在html中的<table>基本上都被用来展示一些重要的数据,有时候我们需要从html中的某些table里抓取数据,今天就简单介绍一下怎样从网页上抓取table标签中的数据。
利用aardio实现这个需求比较容易,一般情况下,我们用web.form加载网页后,通过wb.getEle()或wb.queryEles()得到table节点,然后用com.each()遍历其中的行、列就可以了得到其中单元格的数据了。先看一个简单的示例
示例1:
-
import win.ui;
-
/*DSG{{*/
-
var winform = win.form(text="读取/修改 html 表格";right=687;bottom=447;max=false)
-
winform.add(
-
btnModifyCell={cls="button";text="修改表格内容";left=192;top=216;right=352;bottom=248;z=4};
-
btnReadcell={cls="button";text="读取表格内容";left=16;top=216;right=176;bottom=248;z=3};
-
custom={cls="custom";text="自定义控件";left=16;top=8;right=672;bottom=208;edge=1;z=1};
-
listview={cls="listview";left=16;top=256;right=672;bottom=432;fullRow=1;edge=1;z=2}
-
)
-
/*}}*/
-
-
import web.form;
-
var wb = web.form(winform.custom);
-
wb.html = /**
-
<meta charset="utf-8"/>
-
<table id="mytable">
-
<thead>
-
<tr>
-
<th>ID</th>
-
<th>Data</th>
-
</tr>
-
</thead>
-
<tbody>
-
<tr>
-
<td>A</td>
-
<td>第一行</td>
-
</tr>
-
<tr>
-
<td>B</td>
-
<td>第二行</td>
-
</tr>
-
<tr>
-
<td>C</td>
-
<td>第三行</td>
-
</tr>
-
</tbody>
-
</table>
-
<style type="text/css">
-
table{
-
width: 100%;
-
border-collapse: collapse;
-
}
-
th,td{
-
border: 1px solid #999;
-
text-align: center;
-
padding: 10px 0;
-
}
-
table thead tr{
-
background-color: #008c8c;
-
color: #fff;
-
}
-
</style>
-
**/
-
wb.wait();
-
-
winform.btnReadcell.oncommand = function(id,event){
-
var header = {}
-
var datas = {}
-
for i, row in com.each(wb.getEle("mytable").rows) {
-
var rowtab = {}
-
for j, cell in com.each(row.cells){
-
if(i==1){
-
table.push(header, cell.innerText)
-
}else{
-
//读html中的table字段
-
rowtab[ header[j] ] = cell.innerText
-
}
-
}
-
if(i>1) table.push(datas,rowtab)
-
}
-
winform.listview.setColumns(header)
-
datas = table.mix(datas,{["fields"]=header})
-
winform.listview.setTable( datas )
-
}
-
-
winform.btnModifyCell.oncommand = function(id,event){
-
for i, row in com.each(wb.getEle("mytable").rows) {
-
for j, cell in com.each(row.cells){
-
if(i>1){/*不改动列头*/
-
//修改html中的table字段
-
cell.innerText = cell.innerText ++ "♬️"
-
}
-
}
-
}
-
}
-
-
winform.show();
-
win.loopMessage();
复制代码
效果如下:
示例1非常简单,但是html内容是我们自己写的,只有最简单的一个table,并不是真实网络世界的table。
下面,我们对示例1的代码稍微修改一下,尝试从一个真实的网页中读取表格数据。
示例2:
-
import win.ui;
-
/*DSG{{*/
-
var winform = win.form(text="读取/修改 html 表格";right=687;bottom=447)
-
winform.add(
-
btnModifyCell={cls="button";text="修改表格内容";left=192;top=216;right=352;bottom=248;dl=1;dt=0.48;z=4};
-
btnReadcell={cls="button";text="读取表格内容";left=16;top=216;right=176;bottom=248;dl=1;dt=0.48;z=3};
-
custom={cls="custom";text="自定义控件";left=16;top=8;right=672;bottom=208;db=0.54;dl=1;dr=1;dt=1;edge=1;z=1};
-
listview={cls="listview";left=16;top=256;right=672;bottom=432;db=1;dl=1;dr=1;dt=0.57;edge=1;fullRow=1;z=2}
-
)
-
/*}}*/
-
-
import web.form;
-
var wb = web.form(winform.custom);
-
wb.noScriptErr=true;
-
-
wb.go("https://www.amac.org.cn/informationpublicity/institutionalpublicity/gmjjglrgs/")
-
wb.wait();
-
-
winform.btnReadcell.oncommand = function(id,event){
-
var eles = wb.queryEles(tagName="table")
-
if(!eles){return;}
-
var header = {}
-
var datas = {}
-
for i, row in com.each(eles[1].rows) {
-
var rowtab = {}
-
for j, cell in com.each(row.cells){
-
if(i==1){
-
table.push(header, cell.innerText)
-
}else{
-
//读html中的table字段
-
rowtab[ header[j] ] = cell.innerText
-
}
-
}
-
if(i>1) table.push(datas,rowtab)
-
}
-
table.push(header,"") //解决win10系统最后1列可能不显示的问题
-
winform.listview.setColumns(header)
-
datas = table.mix(datas,{["fields"]=header})
-
winform.listview.setTable( datas )
-
}
-
-
winform.btnModifyCell.oncommand = function(id,event){
-
var eles = wb.queryEles(tagName="table")
-
if(!eles){return;}
-
for i, row in com.each(eles[1].rows) {
-
for j, cell in com.each(row.cells){
-
if(i>1){/*不改动列头*/
-
//修改html中的table字段
-
cell.innerText = cell.innerText ++ "♬️"
-
}
-
}
-
}
-
}
-
winform.show();
-
win.loopMessage();
复制代码
效果如下:
看,我们成功获取了外部网页的表格数据,并显示到listview控件中。
但是如果你仔细观察这个网页,你会发现其实它显示数据时使用了分页技术,每次table中只有10行数据,上面的代码只是将第一页的数据加载到listview中了。
实际上,该表格中所有的记录有156条,有点遗憾,我们每次只能从wb对象中得到10条记录,怎样才能一次抓取到表格中全部的记录呢?
很容易就发现,点击不同的页码后,jQuery在后台发送了"findMutualFundHousePage?pageNo=2&pageSize=10"这个请求,
从这个请求字符串大概可以明白,参数pageNo=2表示要请求的页码,pageSize=10表示每页显示的记录数,
然后把这个请求链接粘贴到浏览器地址栏,回车,发现返回的是json格式的数据集,呵呵,这就好办了!
为了一次显示所有记录数, 我们不再采用在webform中寻找节点这种方法了,改用inet.http + web.json来获取数据。
示例3:
-
import win.ui;
-
/*DSG{{*/
-
var winform = win.form(text="读取所有公募基金管理人名录";right=687;bottom=447)
-
winform.add(
-
btngetAlldata={cls="button";text="读取所有公募基金管理人名录";left=16;top=216;right=344;bottom=248;dl=1;dt=0.48;z=3};
-
custom={cls="custom";text="自定义控件";left=16;top=8;right=672;bottom=208;db=0.54;dl=1;dr=1;dt=1;edge=1;z=1};
-
listview={cls="listview";left=16;top=256;right=672;bottom=432;db=1;dl=1;dr=1;dt=0.57;edge=1;fullRow=1;z=2}
-
)
-
/*}}*/
-
-
import web.form; //仅供在窗体中显示网页
-
var wb = web.form(winform.custom);
-
wb.noScriptErr=true;
-
wb.go("https://www.amac.org.cn/informationpublicity/institutionalpublicity/gmjjglrgs/")
-
wb.wait();
-
-
import inet.http;
-
import web.json;
-
-
winform.btngetAlldata.oncommand = function(id,event){
-
var eles = wb.queryEles(tagName="table")
-
if(!eles){return;}
-
-
//获取网页中表格头文本到listview列头
-
var header = {}
-
for i, cell in com.each(eles[1].rows[0].cells){
-
table.push(header, cell.innerText)
-
}
-
table.push(header,"")
-
winform.listview.setColumns(header)
-
-
//获取表格中所有的记录
-
var ret = inet.http().get("https://www.amac.org.cn/portal/front/mutualFund/findMutualFundHousePage?pageNo=1&pageSize=1000")
-
var datas = web.json.parse(ret)
-
datas = datas["data"].data.dataList;
-
table.mix( datas, {["fields"]={"lineId","houseName","registerAddr","officeAddr"}} )
-
winform.listview.setTable( datas )
-
}
-
-
winform.show();
-
win.loopMessage();
复制代码
效果如下: