htmlagilitypack和动态内容问题

Chy*_*kov 12 c# dynamic-content html-agility-pack

我想创建一个web scrapper应用程序,我想用webbrowser控件,htmlagilitypack和xpath.

现在我设法创建了xpath生成器(我为此目的使用了webbrowser),它工作正常,但有时我无法动态(通过javascript或ajax)生成内容.另外我发现当webbrowser控件(实际上是IE浏览器)生成一些额外的标签,如"tbody",而htmlagilitypack`htmlWeb.Load(webBrowser.DocumentStream);`没有看到它.

另一个说明.我发现下面的代码实际上抓住了当前的网页源代码,但我无法提供htmlagilitypack`(mshtml.IHTMLDocument3)webBrowser.Document.DomDocument;`

你能帮帮我吗?

Nic*_*ick 23

我花了好几个小时试图让HtmlAgilityPack从网页上呈现一些ajax动态内容,我从一个无用的帖子转到另一个,直到我找到了这个.

答案隐藏在初始帖子的评论中,我认为我应该理顺它.

这是我最初使用的方法,但不起作用:

private void LoadTraditionalWay(String url)
{
    WebRequest myWebRequest = WebRequest.Create(url);
    WebResponse myWebResponse = myWebRequest.GetResponse();
    Stream ReceiveStream = myWebResponse.GetResponseStream();
    Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
    TextReader reader = new StreamReader(ReceiveStream, encode);
    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
    doc.Load(reader);
    reader.Close();
}
Run Code Online (Sandbox Code Playgroud)

WebRequest不会呈现或执行呈现缺少内容的ajax查询.

这是有效的解决方案:

private void LoadHtmlWithBrowser(String url)
{
    webBrowser1.ScriptErrorsSuppressed = true;
    webBrowser1.Navigate(url);

    waitTillLoad(this.webBrowser1);

    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
    var documentAsIHtmlDocument3 = (mshtml.IHTMLDocument3)webBrowser1.Document.DomDocument; 
    StringReader sr = new StringReader(documentAsIHtmlDocument3.documentElement.outerHTML); 
    doc.Load(sr);
}

private void waitTillLoad(WebBrowser webBrControl)
{
    WebBrowserReadyState loadStatus;
    int waittime = 100000;
    int counter = 0;
    while (true)
    {
        loadStatus = webBrControl.ReadyState;
        Application.DoEvents();
        if ((counter > waittime) || (loadStatus == WebBrowserReadyState.Uninitialized) || (loadStatus == WebBrowserReadyState.Loading) || (loadStatus == WebBrowserReadyState.Interactive))
        {
            break;
        }
        counter++;
    }

    counter = 0;
    while (true)
    {
        loadStatus = webBrControl.ReadyState;
        Application.DoEvents();
        if (loadStatus == WebBrowserReadyState.Complete && webBrControl.IsBusy != true)
        {
            break;
        }
        counter++;
    }
}
Run Code Online (Sandbox Code Playgroud)

我们的想法是使用能够呈现ajax内容的WebBrowser加载,然后等待页面完全呈现,然后使用Microsoft.mshtml库将HTML重新解析为敏捷包.

这是我可以访问动态数据的唯一方法.

希望它可以帮助某人

  • 干得好,尼克!感谢您发布解决方案 - 这对我来说非常有用!真是个琐事!我将补充说,添加引用时MSHTML被命名为"Microsoft HTML对象库". (3认同)

小智 -7

使用 HTML Agility 包文档的以下方法。

htmlAgilityPackDocument.LoadHtml(this.browser.DocumentText);
Run Code Online (Sandbox Code Playgroud)

或者

if (this.browser.Document.GetElementsByTagName("html")[0] != null)
    _htmlAgilityPackDocument.LoadHtml(this.browser.Document.GetElementsByTagName("html")[0].OuterHtml);
Run Code Online (Sandbox Code Playgroud)