【发布时间】:2023-03-06 06:03:01
【问题描述】:
我正在尝试编写一个网络抓取应用程序,但在运行一些 JavaScript 以在页面加载后生成我需要的数据的网站时遇到问题。
页面完成加载后,页面运行此 javascript:
$(document).ready( function() {
$("#periodSelect, #typeSelect").change(spotSystemPrice.load);
spotSystemPrice.load();
完成后,它会使用数据填充一个 div (id="spotSystemPriceOutput")。
我尝试仅使用 WebBrowser 类来执行此操作,但 InvokeScript 只允许您调用函数,而不是调用方法。到目前为止,我发现的最接近的解决方案是使用调用该方法的 MSHTML.dll 插入一些 javascript。这似乎有效,但我需要一些帮助将 div 输出加载到字符串中,或者我什至可以使用完整的正文 html。我对 C# 很陌生,所以我完全不了解这个,我认为我需要的最后一步将非常简单,所以我只需要你们中的一位专家来帮助我:)
这是我正在使用的代码。任何可以帮助我完成它的建议,甚至是完全不同的解决方案都将不胜感激。
WebBrowser wb = new WebBrowser();
wb.Navigate(URL);
while (wb.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
var doc = (IHTMLDocument2)wb.Document.DomDocument;
var headItems = (IHTMLElementCollection)doc.all.tags("head");
var scriptObject = (IHTMLScriptElement)doc.createElement("script");
scriptObject.type = @"text/javascript";
scriptObject.text = "spotSystemPrice.load();";
var node = (IHTMLDOMNode)headItems.item(null, 0);
node.appendChild((IHTMLDOMNode)scriptObject);
有趣的是,如果我将 javascript 注入更改为“spotSystemPrice.load(); alert('');” 在消息框上单击“确定”后,我可以使用文本可视化器在对象资源管理器中查看结果,它为我提供了 (((((mshtml.HTMLHeadElementClass)(node)).document).body).innerHTML 的表达式引用。向 javascript 添加警报会如何改变我的结果?我需要等待某种 onComplete 事件吗?
更新:我还发现这看起来很有用Calling javascript object method using WebBrowser.Document.InvokeScript,我将代码修改为:
WebBrowser wb = new WebBrowser();
wb.Navigate(URL);
while (wb.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
string JScript = "spotSystemPrice.load();";
object[] args = { JScript };
wb.Document.InvokeScript("eval", args);
while (wb.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
但这仍然没有给我 div 元素中的数据。但由于某种原因,如果我的 javascript 出现“alert('');”甚至不要尝试调用该方法,我需要的数据就在那里!这是怎么回事?我很困惑。
【问题讨论】:
-
这看起来很相似。但是,就像我上面提到的,我对编程/c# 非常陌生,所以我无法将该解决方案转化为我的问题。我上面写的代码是从这里的另一篇文章中复制和修改的。现在调用了 javascript,我只需要一些帮助来提取新的 html。
标签: c# javascript webbrowser-control mshtml