Cómo analizar un FORM de WebResponse en un cuerpo POST de una WebRequest

c# html-agility-pack webrequest webresponse web-scraping

Pregunta

Soy nuevo en esto, este es mi viaje virgen, la tarea en cuestión es crear una transacción en C # que navegue a través del flujo de páginas de una aplicación web a través de WebRequest / WebResponse. Tengo el mecanismo de solicitud / respuesta funcionando, las cookies y todo (puedo ejecutar con éxito una transacción con valores codificados para las URL POST y los cuerpos POST), la dificultad está en generar el cuerpo POST dinámico y la URL POST para WebRequest a partir de los pares de valores de WebRequest . Esencialmente, una vez que el flujo se inicia con la primera solicitud de Web, que tiene siempre la misma URL estática y el cuerpo "codificado", cada solicitud siguiente se crea a partir de los pares de valores de FORM de la Respuesta anterior, por ejemplo: parte del FORM que está en la Respuesta (He reemplazado los corchetes de apertura y cierre de HTML por cuadrados, no estoy seguro de cómo pegar HTML directamente aquí):

    <form id="expressform" method="post" action="">
<div>
    <input type="hidden" name="ScreenData.widgets.modified" value=""/><input type="hidden" name="ScreenData.header.hidden.name" value="ScreenData.widgets.modified"/><input type="hidden" name="ScreenData.marshalled" value="true"/><input type="hidden" name="ScreenData.header.hidden.name" value="ScreenData.marshalled"/><input type="hidden" name="isCreateAccountWizard" value="true"/><input type="hidden" name="ScreenData.header.hidden.name" value="isCreateAccountWizard"/>
    <input type="hidden" name="versionPoint" value="77777"/>

y luego algunas áreas de texto en el formulario para enviar valores, como esto:

<tr>
    <td class="dataOut" style="padding-left:30px">
        <textarea name="ScreenData.sicInfo.natureOfBusiness" rows="5"  cols="60" class="dataOut" onmouseup="textAreaCounter(this,250);;" onkeypress="textAreaCounter(this,250);;" onkeyup="textAreaCounter(this,250);;" onchange="markDataDirty(this);;"></textarea> 
    </td>
</tr>

y luego en Enviar está la URL:

 <a class="detailBtnOn" href="javascript:submitForm('express?displayAction=CreateAccountWizard&amp;saveAction=SaveCreateSICCode&amp;flow=forward&amp;saveActionToken=84454A7D-50FE-5856-CE17-916B70EDFE1A&amp;flowToken=CF3827F4-1DE7-54B1-D87B-D72F01C454C3')">Submit</a>

Y luego el próximo WebResponse debería tener esto en su cuerpo POST:

ScreenData.widgets.modified=&ScreenData.header.hidden.name=ScreenData.widgets.modified&ScreenData.marshalled=true&ScreenData.header.hidden.name=ScreenData.marshalled&isCreateAccountWizard=true&ScreenData.header.hidden.name=isCreateAccountWizard&versionPoint=77777&ScreenData.commonHeaderInfo.accountName=SomeAccountName&ScreenData.commonHeaderInfo.effectiveDate=08%2F01%2F2011&ScreenData.sicInfo.natureOfBusiness=business&ScreenData.sicInfo.sic=7777&ScreenData.widgets.modified=ScreenData.sicInfo.natureOfBusiness&ScreenData.widgets.modified=ScreenData.sicInfo.sic

y esto como una URL:

express?displayAction=CreateAccountWizard&saveAction=SaveCreateSICCode&flow=forward&saveActionToken=84454A7D-50FE-5856-CE17-916B70EDFE1A&flowToken=CF3827F4-1DE7-54B1-D87B-D72F01C454C3 

Pero no solo no puedo descubrir cómo construir este motor de análisis, sino que tampoco puedo tomar pares de valores del FORM. Estoy tratando de usar AgilityPack, aquí hay un poco que debería al menos imprimir el contenido "importante" de los FORMULARIOS:

var page = new HtmlDocument();
page.OptionReadEncoding = false;
var stream = HttpWResponse.GetResponseStream(); 
page.Load(stream);
foreach (var f in page.DocumentNode.Descendants("form"))
{
    foreach (var d in page.DocumentNode.Descendants("div"))
    {
        Loggers.EventsLogger.Info("");
        Loggers.EventsLogger.Info((f.GetAttributeValue("name", null) ?? f.GetAttributeValue("id", "<no name>")) + ": ");
        Loggers.EventsLogger.Info("");
        Loggers.EventsLogger.Info(f.GetAttributeValue("method", "<no method>") + ' ');
        Loggers.EventsLogger.Info("");
        Loggers.EventsLogger.Info(f.GetAttributeValue("action", "<no action>"));

        foreach(var i in f.Descendants("input"))//{

        {
            Loggers.EventsLogger.Info("");
            Loggers.EventsLogger.Info('\t' + (i.GetAttributeValue("name", null) ?? f.GetAttributeValue("id", "<no name>")));
            Loggers.EventsLogger.Info("");
            Loggers.EventsLogger.Info(" (");
            Loggers.EventsLogger.Info("");
            Loggers.EventsLogger.Info(i.GetAttributeValue("type", "<no type>"));
            Loggers.EventsLogger.Info("");
            Loggers.EventsLogger.Info("): " + i.GetAttributeValue("value", "<no value>"));
        }
        Loggers.EventsLogger.Info("");
        Loggers.EventsLogger.Info("");
    }
}

pero solo imprime esto:

INFO  EventsLogger - 
INFO  EventsLogger - expressform: 
INFO  EventsLogger - 
INFO  EventsLogger - post 

(Si me deshago del bit "div" - foreach (var d en page.DocumentNode.Descendants ("div")), - nada cambia)


Cualquier ayuda o sugerencia sobre lo que está sucediendo con el analizador de impresión FORM y cómo construir un motor de análisis para la creación de solicitudes de respuestas sería muy apreciado.

Respuesta popular

compruebe esto Analizando la página HTML con HtmlAgilityPack y este http://refactoringaspnet.blogspot.com/2010/04/using-htmlagilitypack-to-get-and-post_19.html y http://htmlagilitypack.codeplex.com/discussions/ 247206 y ¿Cómo obtendría las entradas de un formulario determinado con HtmlAgility Pack? Lang: C # .net

EDITAR - un poco más de información:

pasa por foreach sobre los formularios en el documento HTML pero va después de los DIV en el próximo foreach sin hacer referencia al formulario actual ... en el bucle foreach interno necesita algo similar a

foreach (var d in f.SelectNodes(".//div"))

y

foreach (var i in d.SelectNodes(".//input"))


Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow