Как разобрать FORM из WebResponse в тело POST WebRequest

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

Вопрос

Я новичок в этом, это мое девственное путешествие, задача заключается в создании транзакции на C #, которая будет перемещаться по потоку страниц веб-приложения через WebRequest / WebResponse. Я получил механизм запроса / ответа, куки и все (я могу успешно выполнить транзакцию с жестко заданными значениями для POST-адресов и POST-объектов), сложность заключается в создании динамического тела POST и URL-адреса POST для WebRequest из пар значений WebRequest , По сути, как только поток запускается с первым WebRequest, который всегда имеет один и тот же статический URL и «жесткий код», каждый следующий запрос строится из пар значений FORM предыдущего Response, например: часть FORM, которая находится в Response (Я заменил открывающие и закрывающие скобки HTML квадратными, не уверен, как вставить HTML прямо сюда):

    <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"/>

а затем некоторые текстовые области в форме для представления значений, например:

<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>

а затем в поле «Отправить» есть 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>

И тогда следующий WebResponse должен иметь это в своем тесте 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

и это как URL:

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

Но не только я не могу понять, как построить этот механизм синтаксического анализа, я даже не могу захватить пары значений из FORM. Я пытаюсь использовать AgilityPack, вот немного, что должно хотя бы распечатать «важный» контент FORM:

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

но он только распечатывает это:

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

(если я избавлюсь от бит «div» - foreach (var d в page.DocumentNode.Descendants («div»)), - ничего не меняется)


Любая помощь или предложения о том, что происходит с анализатором FORM, и как создать механизм синтаксического анализа для создания запросов от ответов, будет с благодарностью.

Популярные ответы

проверьте это на странице Parsing HTML с помощью HtmlAgilityPack и http://refactoringaspnet.blogspot.com/2010/04/using-htmlagilitypack-to-get-and-post_19.html и http://htmlagilitypack.codeplex.com/discussions/ 247206 и как получить входные данные из определенной формы с помощью пакета HtmlAgility Pack? Lang: C # .net

EDIT - дополнительная информация:

вы зацикливаетесь через foreach над формами в документе HTML, но вы идете после DIV в следующем foreach, не ссылаясь на текущую форму ... во внутреннем цикле foreach вам нужно что-то похожее

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

а также

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


Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow