【问题标题】:invoking Javascript to return data for web scrape调用 Javascript 以返回数据以进行网络抓取
【发布时间】: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


【解决方案1】:

如果脚本中已经存在函数 spotSystemPrice.load 你可以试试 InvokeScript:

wb.Document.InvokeScript("spotSystemPrice.load");

请注意,我没有在函数末尾使用 ()。在此之后将加载更多数据,您需要等到所有数据再次加载,因此重用您的代码:

while (wb.ReadyState != WebBrowserReadyState.Complete) Application.DoEvents();

您也可以等到 wb.Document.Body 不为空和/或您的 div 包含数据。

while (wb.Document.Body == null) Application.DoEvents();
while (wb.Document.GetElementById("spotSystemPriceOutput").InnerHtml.length == 0) Application.DoEvents();

但此时我会实施某种超时以防万一发生故障,这样它就不会永远卡在那里,但值得一试。

【讨论】:

  • 我试过这样做,但执行后我仍然没有得到任何数据:wb.Document.GetElementById("spotSystemPriceOutput").InnerHtml 或查看整个页面:wb. Document.Body.InnerHtml
  • 调用它后,如果它“导航”或加载外部数据,您需要等到新内容加载完毕。像以前一样检查 WebBrowserReadyState.Complete。
  • 对不起,我应该提到我还尝试在调用脚本后等待 ReadyState.Complete,但这不起作用。 div 元素仍然是空白的。
猜你喜欢
  • 2022-01-25
  • 2021-10-27
  • 2022-01-12
  • 2021-12-06
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多