抓取AJAX数据

本示例可参考示例文件"CaseStudy\WebViewer\网页自动化.Table"的窗口"抓取股票数据"

前面几节实现的网页数据抓取和自动登录,都有一个前提,就是有一个目标网页要跳转,Foxtable在异步等待网页加载完毕后进行判断处理。

但是很多场景并没有网页跳转,而是通过AJAX局部动态更新数据和网页内容,这种情况用WebViewer处理起来同样简单。

本节的任务是抓取以下网页的股票交易数据:

http://data.10jqka.com.cn/funds/ggzjl/

当我们在这个页面单击不同的页码,或者单击"下一页"时,并不会跳转网页,而是通过AJAX刷新table元素的数据。

模拟单击下一页以及数据的抓取都比较简单,和前面的示例无异。

最大的问题是如何判断AJAX执行成功了呢?

原理:

AJAX刷新数据后,网页某些元素的内容必定会发生变化,我们通过跟踪关键元素的内容,即可判断本次AJAX数据刷新是否成功。

以上面的网站为例,有一个显示页码和总页数的元素,其class为"page_info",我们只需跟踪这个元素的内容变化,即可判断出本次AJAX刷新是否成功。

测试代码:

'''Async
Dim
wv As WebViewer = e.Form.Controls("WebViewer1").WebViewer
wv.CoreWebView2.Navigate("http://data.10jqka.com.cn/funds/ggzjl/") '打开同花顺页面
Dim
ret As Integer = Await wv.NavigationTaskAsync(10) '异步等待网页加载完成,等待时间为10秒
If
ret <> 0 Then
    MessageBoxA.Show(
"网页加载失败,终止程序")
   
Return
End
If
Dim
pageInfo = wv.querySelector(".page_info") '这是一个关键元素,显示了页码和总页数,通过这个元素的内容可以判断换页是否成功
Dim
pageString As String = (Await pageInfo.textContent).Trim("""")
Dim
pageCount As Integer = pageString.Split("/")(1) '获取总页数
For
page As Integer = 0 To 1 '只获取两页数据,如果要获取所有数据,请将1改为pageCount -2
   
Dim stRows = wv.querySelectorAll("table.m-table.J-ajax-table tbody tr") '获得所有数据行
   
Dim rowsCount As Integer = Await stRows.length '获得总行数
   
For r As Integer = 0 To rowsCount - 1 '遍历行
       
Dim dr As DataRow = DataTables("资金表即时").AddNew()
        dr(
"序号") = CInt((Await stRows(r).cells(0).innerText).Trim(""""))
        dr(
"股票代码") = (Await stRows(r).cells(1).innerText).Trim("""")
        dr(
"股票简称") = (Await stRows(r).cells(2).innerText).Trim("""")
        dr(
"最新价") = val((Await stRows(r).cells(3).innerText).Trim(""""))
        dr(
"涨跌幅") = val((Await stRows(r).cells(4).innerText).Trim("""").Trim("%"))
        dr(
"换手率") = val((Await stRows(r).cells(5).innerText).Trim("""").Trim("%"))
        dr(
"流入资金(元)") = val((Await stRows(r).cells(6).innerText).Trim(""""))
        dr(
"流出资金(元)") = val((Await stRows(r).cells(7).innerText).Trim(""""))
        dr(
"净额(元)") = val((Await stRows(r).cells(8).innerText).Trim(""""))
        dr(
"成交额(元)") = val((Await stRows(r).cells(9).innerText).Trim(""""))
   
Next
   
Dim nextPage = wv.xpathQuery("//a[@class='changePage' and text()='下一页']") '取得下一页元素
   
If Await nextPage.isNull() Then
       
Return '如果没有下一页这个元素,说明已经是最后一页,直接退出
   
End If
   
Dim oldpage As String = Await pageInfo.textContent '获得当前页码
   
Dim success As Boolean = False
    nextPage.click()
'模拟单击下一页按钮
   
For m As Integer = 1 To 20 '每0,5秒查询一次页码,10秒内页码没发生变化的话,则认为刷新失败
       
Await task.Delay(500) '间隔0.5秒
       
Dim nepage As String = Await pageInfo.textContent '获得新页码
       
If nepage <> oldpage Then '如果页码有变化
            success =
True '说明已经跳转到下一页
           
Exit For
       
End If
   
Next
   
If success = False Then '如果跳转到下一页失败
        MessageBoxA.Show(
"获取到第" & (page + 1) & "页数据时失败")
       
Return
   
End If
   
Await task.Delay(3000) '延迟3秒,避免被反爬,根据需要调整时间,可选
Next


本页地址:http://www.foxtable.com/webhelp/topics/6997.htm