用 VB 的网页 WebBrowser 控件抓网页源码,很多人第一反应是源码 `DocumentText` 或者 `InnerText`。这两个属性确实能拿到东西,网页但拿到的源码东西经常不是你要的。
`WebBrowser1.DocumentText` 返回的网页是当前文档的 HTML,听起来没问题。源码可你要是网页拿它去解析一段动态加载的页面,会发现里面空空如也——JavaScript 还没跑完呢,源码DOM 根本没构建完整。网页更坑的源码是,有时候它返回的网页源码和你右键“查看源代码”看到的完全不一样,因为浏览器已经对 DOM 做了修改,源码`DocumentText` 反映的网页是修改后的状态。
真正接近原始响应内容的源码是 `Document.documentElement.outerHTML`。这个属性返回的网页是当前 DOM 树的序列化结果,包含所有被脚本改动过的节点。如果你要的是“浏览器最终渲染出来的结构”,用它就对了。写法也简单:
Dim html As String html = WebBrowser1.Document.DocumentElement.OuterHtml但这里有个前提:页面必须加载完毕。你如果在 `DocumentCompleted` 事件里直接取,遇到框架页或者异步请求多的站点,照样拿不全。我自己的做法是加一个延时,或者监听 `DocumentCompleted` 的触发次数——有些页面会触发多次,最后一次才是真正加载完。
那如果我要的是服务器返回的原始 HTML 呢?就是那种没被浏览器加工过的、原汁原味的源码。`WebBrowser` 控件本身不直接暴露这个。它底层用的是 `IWebBrowser2` 接口,你可以通过 `IPersistStreamInit` 或者 `IHTMLDocument2` 去拿,但代码量不小。更省事的办法是用 `WinHttpRequest` 或者 `XMLHTTP` 单独发一次请求,把响应文本拿回来。这样拿到的就是原始源码,跟浏览器渲染无关。
举个实际例子。之前帮人写个小工具,要抓某个政府公开页面的表格数据。用 `WebBrowser` 加载后取 `DocumentText`,发现表格是空的。换成 `outerHTML`,表格出来了,但数据行是 JavaScript 根据接口返回的 JSON 动态生成的。最后用 `XMLHTTP` 直接请求那个 JSON 接口,反而比解析 HTML 更稳。所以工具选型要看目标页面怎么渲染的。
还有一个细节:编码问题。`DocumentText` 有时候会把中文显示成乱码,尤其是页面声明了 GB2312 但浏览器按 UTF-8 解析的时候。`outerHTML` 一般没这个问题,因为它基于已经解析好的 DOM。如果非要处理原始字节流,用 `ADODB.Stream` 读响应体,手动指定字符集,比依赖控件自动识别靠谱。
代码写起来不复杂,关键是搞清楚你要的是“渲染后的 DOM”还是“服务器原始响应”。前者用 `outerHTML`,后者用独立 HTTP 请求。别在 `DocumentText` 上浪费太多时间,它是个半吊子方案,既不是原始源码,也不保证是完整 DOM。
另外提醒一句:`WebBrowser` 控件依赖 IE 内核,很多现代网站已经不再兼容。你要是拿它去抓 React 或 Vue 写的单页应用,大概率会失望。这时候要么换 `WebView2`,要么干脆放弃浏览器控件,直接用 HTTP 库加 HTML 解析器。工具是死的,思路得活。
顶: 15踩: 76481






评论专区