Htmlagilitypack y problema de contenido dinámico

c# dynamic-content html-agility-pack

Pregunta

Hola a todos.

Quiero crear una aplicación web de chatarra y quiero hacerlo con el control de navegador web, htmlagilitypack y xpath.

En este momento logré crear el generador xpath (usé el navegador web para este propósito), que funciona bien, pero a veces no puedo capturar dinámicamente (a través de javascript o ajax) el contenido generado. También descubrí que cuando el control del navegador web (en realidad el navegador IE) genera algunas etiquetas adicionales como "tbody", mientras que nuevamente htmlagilitypack `htmlWeb.Load (webBrowser.DocumentStream);` no lo ve.

otra nota. Descubrí que el siguiente código en realidad toma la fuente de la página web actual, pero no pude suministrarle el htmlagilitypack `(mshtml.IHTMLDocument3) webBrowser.Document.DomDocument;`

¿Puedes ayudarme con eso por favor? Gracias

Respuesta popular

Acabo de pasar horas intentando que HtmlAgilityPack renderice un contenido dinámico ajax de una página web y pasé de una publicación inútil a otra hasta que encontré esta.

La respuesta está oculta en un comentario en la publicación inicial y pensé que debía aclararlo.

Este es el método que usé inicialmente y no funcionó:

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();
}

WebRequest no procesará ni ejecutará las consultas ajax que representan el contenido faltante.

Esta es la solución que funcionó:

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++;
    }
}

La idea es cargar usando el WebBrowser que es capaz de representar el contenido ajax y luego esperar hasta que la página se haya procesado completamente antes de usar la biblioteca Microsoft.mshtml para volver a analizar el HTML en el paquete de agility.

Esta era la única forma en que podía acceder a los datos dinámicos.

Espero que ayude a alguien



Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué