以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.net/bbs/index.asp)
--  专家坐堂  (http://foxtable.net/bbs/list.asp?boardid=2)
----  [免费开源]教你用狐表做爬虫获取网页元素。狐表HttpClient+第三方xPath分析工具HtmlAgilityPack。用主流的思路爬取网页,获取表格数据,配合狐表的定时器,快速多掌握一门工作业务技术  (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=168836)

--  作者:chen37280600
--  发布时间:2021/5/24 10:52:00
--  [免费开源]教你用狐表做爬虫获取网页元素。狐表HttpClient+第三方xPath分析工具HtmlAgilityPack。用主流的思路爬取网页,获取表格数据,配合狐表的定时器,快速多掌握一门工作业务技术

(快速浏览杰哥分享过的所有经验汇总,点击跳转


0需求

最近大宗材料价格变大大,客户想每天早上,系统根据贵金属的价格,自动更新采购单据的成本

然后我看了一下之前广为流传的2014年的帖子
[分享]自动获取网页中表数据,保存到狐表TABLE中方法 ,链接:http://foxtable.com/bbs/dispbbs.asp?BoardID=2&ID=49278&skin=0

感觉有点问题:
1它利用了ie内核的WebBrowser去模拟打开网页。IE兼容性很差,稍微新型的网站都是各种js报错,而且IE已经明确被win10抛弃,不是很靠谱。(后来有不少帖子,说这个模拟打开出现报错,卡主了。)
2它利用了GetElementsByTagName("div")和GetElementById("list_elem"),如果页面有大量重名元素,那定位就困难了,不是很靠谱
3它需要开发者有很强的网页dom结构分析能力,才能定位元素,缺乏一种快速定位的方法。我翻了一下论坛,很多人在找元素的时候都迷惑,在发帖询问。
4代码有点冗长,我看到GetElementsByTagName和GetElementById时,想起来原生的JS开发,太痛苦了...这不科学...

解决:于是我重新整理了一下思路,网页爬虫其实是 获取网页源码+dom结构解析,上面的思路是用Ie内核获取网页源码,然后GetElementsByXxx做dom结构解析。
受限于当时狐表没有HttpClient,只能用这种获取。其实在2017年后,多了HttpClient,这种爬虫方法应该升级

第一步用HttpClient获取网页,第二步然后用xPath去做dom结构解析,效果如下图  (xPath是一种分析网页结构的方法,在python领域非常常见)

此主题相关图片如下:1.png
按此在新窗口浏览图片


1简介
爬虫思路:获取网页然后根据dom分析xPath获取相应的元素
  1. 我们使用httpClient,获取网页
  2. 通过开源的HtmlAgilityPack工具解析Dom
  3. 通过浏览器F12的控制台快速得到xPath路径,提取元素,不需要高强度的网页分析能力了

HtmlAgilityPack网友总结的方法:https://www.cnblogs.com/mq0036/p/11705424.html
HtmlAgilityPack官网文档:https://html-agility-pack.net/parser

接下来用颜色表做案例

此主题相关图片如下:4.png
按此在新窗口浏览图片


2.添加dll

2.1下载dll
支持.net 4.0:


以下内容只有回复后才可以浏览


2.2狐表添加引用
把dll拷贝到狐表的程序根目录后,添加引用,并添加命名空间

此主题相关图片如下:5.png
按此在新窗口浏览图片

命名空间:HtmlAgilityPack 
别名:Hap

2.3重启狐表
重启后检查引用和命名空间是否还存在,存在的话新dll就开始生效了
有可能没添加成功的,认真检查!!

2.4更新代码精灵
用我提供的help.mdb覆盖到你的狐表,例如C:\\foxtable\\Professional,因为我为代码精灵增加了很多关于这个爬虫工具的方法和属性
代码精灵的用法,更多可以参考我之前的帖子:
[免费开源]狐表代码精灵管理器,自己改造狐表的官方代码编辑器,增加提示,自定义事件、方法、对象,非常简单,只需要2步!不用依赖任何第三方工具,永久跟着官方升级  


3获取网页
3.1使用狐表的HttpClient
Dim hc As New HttpClient("http://color.jmtianlu168.com/")
hc.SkipError=True
hc.Resp \'如果中文乱码,请改为 gbk
Dim hd As new Hap.HtmlDocument
hd.LoadHtml(hc.GetData())

3.2从本地网页获取
Dim s As String = FileSys.ReadAllText("S:\\FoxDev\\爬虫监控\\网页.html",Encoding.UTF8)
Dim hd As new Hap.HtmlDocument
hd.LoadHtml(s)


4获取xPath
4.1基础获取
xPath就是根据dom结构,一层层解析路径,提取元素的方法,基础用法如下:(具体可以去w3cSchool看)

此主题相关图片如下:6.png
按此在新窗口浏览图片


我们在谷歌浏览器按F12,打开控制台

此主题相关图片如下:2.png
按此在新窗口浏览图片


得到有偏差的xPath
/html/body/table/tbody/tr[4]/td[4]


4.2路径修正
用F12获取的的xPath多数会有偏差,你可以右键看下源代码,dom结构是否真的如此

此主题相关图片如下:3.png
按此在新窗口浏览图片


此主题相关图片如下:9.png
按此在新窗口浏览图片


其实这里源代码界面能发现,并没有html和body,真实的xPath是
/table/tbody/tr[4]/td[4]

差异的原因:因为chrome会对页面进行一定的修正处理,加上现在很多是ajax异步获取,你用代码请求的dom和当前浏览器展示的dom不一定完全一致,所以这个xPath仅供调试参考,实际上都要进行修正的

调试方法:
可能你会问,我怎么分析啊?
第一步,必须右键查看页面源码,自己分析结构,判断问题出在哪里,最好配合HbuilderX之类的代码整理,更清晰的查看结构

此主题相关图片如下:9.png
按此在新窗口浏览图片

第二步:你可以先到xPath在线小工具http://www.ab173.com/other/xpath.php 
把网页源代码粘贴进去,测试下你的xPath,然后利用`步进逼近`
注意的坑:xPath的路径,是从1开始,而不是从0开始,例如div[1]

此主题相关图片如下:8.png
按此在新窗口浏览图片

/html
/html/body
/html/body/form
/html/body/form/div[2]
//等等逼近你想要的...


5获取节点
5.1获取首个节点
Dim xPath As String = "/table/tbody/tr[4]/td[4]"
Dim hn As Hap.HtmlNode = hd.DocumentNode.SelectSingleNode(xPath)
If hn IsNot Nothing Then
    Output.Show("InnerHtml:" & hn.InnerHtml)
End If

输出结果:InnerHtml:脸红的淡紫色

注意的坑:由于`xPath不一定正确`,所以获取回来的可能是`Nothing`,记得做判断

5.2获取某个节点的相关属性
基础用法:
Dim xPath As String = "/table/tbody/tr[4]/td[4]"
\'获取该节点的父节点
Dim hn As Hap.HtmlNode = hd.DocumentNode.SelectSingleNode(xPath)
If hn IsNot Nothing Then
hn = hn.ParentNode
Output.Show("Parent的OuterHtml:" &  hn.OuterHtml)
End If

类似的用法,还有

  1. FirstChild :获取首个子节点  
  2. LastChild   获取最后一个子节点  
  3. OuterHtml   获取整个节点的html代码  
  4. InnerHtml   获取<>夹住的内部Html代码  
  5. InnerText  获取<>夹住的内部无html的纯文本  
  6. Name   获取Html元素名  
  7. Attributes    获取节点的属性集合 (留意!这玩意很有用的!) 

扩展获取class:获取class之类的属性值
Dim xPath As String = "/table/tbody/tr[4]/td[4]"
Dim hn As Hap.HtmlNode = hd.DocumentNode.SelectSingleNode(xPath)
If hn IsNot Nothing Then
    Dim hars As Hap.HtmlAttributeCollection = hn.Attributes
    Output.Show(hars.Count)

    For Each har As Hap.HtmlAttribute In hars
        Output.Show(har.Name & ":" & har.Value)
    Next
End If

输出结果:
1
style:text-align: center;


5.3获取某节点的子节点的集合

Dim xPath As String = "/table/tbody/tr[4]/td[4]"
Dim hn As Hap.HtmlNode = hd.DocumentNode.SelectSingleNode(xPath)
Dim CNodes As Hap.HtmlNodeCollection = hn.ChildNodes
Output.Show(CNodes.Count)

For Each hn2 As Hap.HtmlNode In CNodes
    Output.Show("InnerHtml:" & hn2.InnerHtml)
Next

5.4获取某个节点集合

Dim xPath As String = "/table/tbody/tr[4]/td[4]"
Dim CNodes As Hap.HtmlNodeCollection  = hd.DocumentNode.SelectNodes(xPath)
Output.Show(CNodes.Count)

For Each hn As Hap.HtmlNode In CNodes
    Output.Show("InnerHtml:" & hn.InnerHtml)
Next
6我要说几句

1爬虫有一定法律风险,请合理利用
2狐表不是专业的爬虫工具,建议只用在简单的网页,更复杂的交互网站,建议学习专业的python爬虫工具
3很多网站有反爬和ip监控,如果你想去爬淘宝、京东,尤其是美团,做梦!
4网站变动,xPath很大可能会变动,就会需要重新编写路径


===============================================================
顺便总结以前分享过的帖子,方便大家学习

联系QQ:2385350359

免费产品:

经验分享:






















[此贴子已经被作者于2024/6/5 18:06:08编辑过]

--  作者:wei0769
--  发布时间:2021/5/24 10:58:00
--  
先顶后看
--  作者:有点蓝
--  发布时间:2021/5/24 11:04:00
--  
多谢分享。

不过普通用户估计看完还是迷糊的。

关键是2个概念,1是会页面源码结构,2是理解xpath。能够上手这2样的用什么工具都无所谓了

--  作者:WELOVEFOX
--  发布时间:2021/5/24 11:32:00
--  
多谢分享。
--  作者:ap9709130
--  发布时间:2021/5/24 12:03:00
--  
 学习一下
--  作者:aix
--  发布时间:2021/5/24 12:31:00
--  
 学习
--  作者:天一生水
--  发布时间:2021/5/24 13:19:00
--  
谢谢分享
--  作者:z769036165
--  发布时间:2021/5/24 14:18:00
--  
学习了
--  作者:shenyl0211
--  发布时间:2021/5/24 16:48:00
--  
学习一下
--  作者:bohe
--  发布时间:2021/5/24 17:20:00
--  
杰哥太牛了图片点击可在新窗口打开查看图片点击可在新窗口打开查看图片点击可在新窗口打开查看
[此贴子已经被作者于2021/5/24 17:20:04编辑过]