抓取网页数据(爬虫)
本示例可参考示例文件"CaseStudy\WebViewer\网页自动化.Table"的窗口"抓取网页数据"
本节的任务是开发一个简单的网页数据抓取程序,也就是常说的爬虫,使用到的知识有上一节介绍的异步等待网页加载,以及内置DOM
要抓取的内容为以下网站的前三页,包括书名、价格和是否有货:
https://books.toscrape.com/
需要注意的是,网站的结构未来可能会发生变化,导致本示例运行失败,但原理基本一样。
Foxtable开发爬虫是非常方便的,以下是本示例的代码,为方便大家学习,我做了详尽的注释:
'''Async
' 目标站点:books.toscrape.com
爬取前三页图书
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
totalPage
As
Integer
= 3
'
定义需要爬取的总页数
DataTables("表A").DataRows.Clear()
'清除现有数据
' 循环遍历每一页
For
pageIndex
As
Integer
= 1
To
totalPage
'
拼接分页URL(Foxtable不支持插值,使用String.Format)
Dim
pageUrl
As
String
pageUrl =
String.Format("https://books.toscrape.com/catalogue/page-{0}.html",
pageIndex)
Dim request =
wv.CreateWebResourceRequest(pageUrl)
'异步加载
+ 超时控制(10秒)
Dim
navRet
As
Integer
=
Await
wv.NavigateWithWebResourceRequestAsync(request, 10)
If
navRet <> 0
Then
wv.Stop()
'停止加载
MessageBoxA.Show(String.Format("第{0}页加载失败,已经抓取{1}",
pageIndex, pageIndex - 1))
Exit
For
End
If
'获取图书集合(.product_pod
为单本书容器)
Dim
bookList = wv.querySelectorAll(".product_pod")
'
获取集合长度(Foxtable标准写法,不能For
Each)
Dim
bookCount
As
Integer
=
Await
bookList.length
'用下标循环遍历每一本图书
For
i
As
Integer
= 0
To
bookCount - 1
Dim
bookItem = bookList(i)
'
下标取值,禁止For
Each
'1.
获取图书名称
h3 > a
Dim nameEle =
bookItem.querySelector("h3
a")
If
Await
nameEle.IsNull()
Then
Continue
For
'
元素不存在则跳过
Dim
bookName
As
String
=
Await
nameEle.title
bookName =
bookName.Trim("""")
'
去除JS自带双引号
' 2.
获取价格
.price_color
Dim priceEle =
bookItem.querySelector(".price_color")
Dim
bookPrice
As
String
=
Await
priceEle.innerText
bookPrice =
bookPrice.Trim("""")
' 3.
获取库存状态
.instock
Dim stockEle =
bookItem.querySelector(".instock")
Dim
stockStatus
As
String
=
Await
stockEle.innerText
stockStatus =
stockStatus.Trim("""").Trim()
' 4.写入到数据表
Dim
dr
As
DataRow = DataTables("表A").AddNew()
dr("书名")
= left(bookName, 64)
dr("价格")
= val (bookPrice.Trim("£"))
If
stockStatus =
"In
stock"
Then
dr("有货")
=
True
End
If
Next
'
模拟人工浏览延迟,降低反爬虫风险,根据需要调整
Await
Task.Delay(1000)
Next
MessageBoxA.Show("前三页图书数据抓取完成!")
不单单是爬虫,Foxtable可以开发任何网页自动化程序,例如抢票之类的。