浏览器抓取网页(写第一个博客前先介绍下我本人:我其实是个硬件工程师 )
优采云 发布时间: 2022-04-11 09:45浏览器抓取网页(写第一个博客前先介绍下我本人:我其实是个硬件工程师
)
在写第一篇博客之前,先啰嗦一下自我介绍一下:我其实是一个硬件工程师,我就是喜欢编程,感觉编程可以大大解放劳动力,所以偶尔写一些小程序来解决小问题日常工作中的问题,而我写的小程序大多是自动化方向的(比如这次要实现的自动填表),会孜孜不倦的寻找编程中遇到的问题的答案,而且因为不是专业的程序员,有些对大家来说很简单。这个问题对我来说并不容易。
通过webbrowser获取静态网页元素比较容易,但是获取动态网页元素就不容易了。在网上搜索了半天,看了很多文章,终于找到了答案。
本文章:《【参考】如何使用Python、C#等语言实现静态网页抓包+动态网页抓包+模拟登录网站》让我学会在开发中使用浏览器人事工具(IE9 中的 F12 和 Chrome 中的 Ctrl+Shift+I)——强大的网页分析工具,让您可以坚定地知道动态网页元素是绝对可用的,但您还没有找到方法。
其实这个文章:"C# WebBrowser Get the Clicked Object"也提到了解决方法,但是我错过了。
直到看了这篇文章:《如何在WebBrowser.Document中获取某个命名空间中的元素?》才真正解决了我要解决的问题,因为里面的网页示例和我要的网页一模一样分析。
该技术的关键在于这行代码: webBrowser1.Document.Window.Frames("frm_xxx").Document.Forms(0).InnerHtml
而不是像这样的帖子:“请教专家,关于WebBrowser控制Jsp网页元素和获取元素数据,在线等。” 5楼说:WebBrowser1.Document.frames.Item(frameindex).Document。documentElement.outerHTML
根据关键代码,我写了一个递归调用函数来查找动态网页元素。这个函数的缺点是遇到同级时,没有Id、InnerText、Name、title、classname、value,或者相同的属性值。使用网页元素时,只能返回第一个匹配的网页元素。解决办法是找到同层的网页元素,然后通过.Parent、NextSibling、Children访问。
Function FindHtmlElement(ByVal FindText As String, ByVal doc As HtmlDocument, ByVal cTagName As String, ByVal cGetAttribute As String, Optional ByVal StrictMatching As Boolean = False) As HtmlElement
'cTagName:检索具有指定html 标记的元素,标记需要输入完整的,缺省时查找所有。
'例如:,不能只输入"i",需要输入"input"
'cGetAttribute :比较的属性类型,取值为:Id、InnerText、Name、title、classname、value、
'Id、InnerText可以通过GetAttribute获取,也可以通过HtmlElement.Id、HtmlElement.InnerText获取,所以代码简化为用GetAttribute获取。
'doc:WebBrowserExt1.Document
'GetAttribute("classname") '例如显示class="commonTable"的值commonTable
'StrictMatching:True严格匹配FindText
Dim i, k As Integer
FindHtmlElement = Nothing
'Step1
For i = 0 To doc.All.Count - 1
If InStr(doc.All.Item(i).GetAttribute(cGetAttribute), FindText) > 0 _
And (Not StrictMatching Or InStr(FindText, doc.All.Item(i).GetAttribute(cGetAttribute)) > 0) And (cTagName = "" Or LCase(cTagName) = LCase(doc.All.Item(i).TagName)) Then
FindHtmlElement = doc.All.Item(i)
'WriteRunLog("Loop1")
Exit Function '找到就退出
End If
Next
For k = 0 To doc.Window.Frames.Count - 1
'2018.3.14 直接递归调用
FindHtmlElement = FindHtmlElement(FindText, doc.Window.Frames.Item(k).Document, cTagName, cGetAttribute, StrictMatching)
If Not FindHtmlElement Is Nothing Then '找到就退出循环
Exit Function
End If
Next
End Function