使用 WebBrowser 访问 DOM
Posted
技术标签:
【中文标题】使用 WebBrowser 访问 DOM【英文标题】:Access the DOM using WebBrowser 【发布时间】:2017-07-18 15:52:11 【问题描述】:在页面上执行 javascript 后,我需要访问 html 文档的 DOM。我有下面的代码连接到 URL 并获取文档。 问题是它在用 javascript 修改后永远不会得到 DOM
public class CustomBrowser
public CustomBrowser()
//
// TODO: Add constructor logic here
//
protected string _url;
string html = "";
WebBrowser browser;
public string GetWebpage(string url)
_url = url;
// WebBrowser is an ActiveX control that must be run in a
// single-threaded apartment so create a thread to create the
// control and generate the thumbnail
Thread thread = new Thread(new ThreadStart(GetWebPageWorker));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
string s = html;
return s;
protected void GetWebPageWorker()
browser = new WebBrowser();
// browser.ClientSize = new Size(_width, _height);
browser.ScrollBarsEnabled = false;
browser.ScriptErrorsSuppressed = true;
//browser.DocumentCompleted += browser_DocumentCompleted;
browser.Navigate(_url);
// Wait for control to load page
while (browser.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
Thread.Sleep(5000);
var documentAsIHtmlDocument3 = (mshtml.IHTMLDocument3)browser.Document.DomDocument;
html = documentAsIHtmlDocument3.documentElement.outerHTML;
browser.Dispose();
希望有人能帮我解决这个问题
【问题讨论】:
请不要将代码发布为图片。将代码作为文本发布。此外,您应该使用事件来查找导航何时完成,而不是使用while
循环 Application.DoEvents()
或 Thread.Sleep()
。
我将代码添加为文本、图像以阐明浏览器中的 dom 与我得到的内容之间的区别
使用替代控件怎么样?例如。 ***.com/questions/790542/…
我用idealtackle.com作为url参数测试了你的代码,每次页面通过javascript加载时都会改变一个图像,在加载它两个不同的时间后,加载了两个不同的图像没问题,如果你想自己看看,在 browser.Dispose() 上放一个断点;然后在第 121 行的快速查看中查看 html,背景图像:每次加载时都会更改。所以我的猜测是这应该是因为您的浏览器版本或运行 javascript 的安全性或类似的东西。
能否请您给我们您的网址,我也核对一下?
【参考方案1】:
如果客户端脚本确实如您所说在 IE7 中执行,则问题可能纯粹是时间问题。即使在文档加载完成后,您也无法确切知道 何时 JS 脚本将被执行。在尝试到达documentElement
之前等待 5 秒在理论上听起来是个好主意;在实践中,该元素可能在此之前存在。或者,也许网络很慢,仅获取 jQuery 脚本本身需要 5 秒。
我建议测试您正在寻找的元素是否存在(img
标签,视情况而定)。类似于
while (browser.Document.GetElementsByTagName("img").Count == 0)
Application.DoEvents();
这样,您就不需要Thread.Sleep
行了。
【讨论】:
该脚本将用于从任何给定的 URL 下载图像,而不是特定的,我认为这不适用于我的情况。 怎么回事?我的回答中没有考虑任何特定的 URL。 我正在寻找的是在执行任何 ajax 或客户端脚本之后获取整个文档 dom。我不是在这里寻找特定元素,我想下载任何给定 html 页面上的所有图像,包括任何标签的背景图像,我已经完成了,除了我无法下载由 ajax 请求或通过客户端脚本。【参考方案2】:我看不到这里正在执行的 js,但我想你可以准确地找到正在更新的元素,并在 onprpertychange 事件时附加一个事件处理程序,就像这里给出的解决方案一样: C# WebBrowser control -- Get Document Elements After AJAX?
如果 js 是按类而不是按想法翻转元素,那么您可以从这里借用逻辑: How to select a class by GetElementByClass and click on it programmically
【讨论】:
【参考方案3】:检查页面在 IE7 中的呈现方式。我猜你缺少的标签是用jQuery添加的,页面上的jQuery 2.2.4版本不支持IE7。我认为 WebBrowser 类确实围绕 IE7,即使您的 PC 上有更新版本的 IE。
如果您拥有该页面,请尝试添加 jQuery 迁移插件。
【讨论】:
不确定以下是否有帮助?:cyotek.com/blog/…、blogs.msdn.microsoft.com/patricka/2015/01/12/…、weblog.west-wind.com/posts/2011/may/21/… 和 ***.com/questions/17922308/… 页面在 IE7 中正确呈现,我将 jQuery 更改为 1.7.1 但没有任何改变。 我确实注意到上面黑色屏幕截图中的 div 类名不是双引号,如果这意味着什么,那么 images2.jpg URL 也不是。我读到 XHTML 需要引号。以上是关于使用 WebBrowser 访问 DOM的主要内容,如果未能解决你的问题,请参考以下文章