mjackson11 Ответов: 2

Перехват отправки данных на C# WebBrowser элемент управления winform


Я пытаюсь очистить веб-страницу. Использование C# и WinForms. Я могу загрузить страницу в веб-браузер, вызвать метод post для формы и получить результаты. Затем я хотел бы изменить дату и повторно отправить форму. К сожалению, элемент управления для выбора даты-это элемент управления только для чтения, управляемый большим количеством ajax-кода (axd-файлов), которые нелегко доступны.

Я подумал, что было бы лучше попытаться перехватить данные POST до того, как они отправятся на сервер, и изменить строку даты.

Кажется, я не могу найти способ получить почтовые данные до того, как они будут отправлены на сервер. Есть ли какой-то способ схватить его, изменить, а затем отправить дальше?

Что я уже пробовал:

public void CompletedHander(object sender,
      WebBrowserDocumentCompletedEventArgs e)
{
      WebBrowser wb = ((WebBrowser)sender);

      HtmlElement button = wb.Document.GetElementById("ctl00$WebSplitter1$tmpl1$ContentPlaceHolder1$HeaderBTN1$btnRetrieve");
      if (button != null)
      {
           _pushed = true;
           button.InvokeMember("click");
      }
}

2 Ответов

Рейтинг:
1

mjackson11

Оказалось, что есть элемент управления, который я могу использовать java для вызова, который создает правильные данные viewstate и post.

public void CompletedHander(object sender,
      WebBrowserDocumentCompletedEventArgs e)
{
    HtmlElement webDatePicker = wb.Document.GetElementById("ctl00_WebSplitter1_tmpl1_ContentPlaceHolder1_dtePickerBegin");

    string szJava = string.Empty;
    szJava = "a = $find(\"ctl00_WebSplitter1_tmpl1_ContentPlaceHolder1_dtePickerBegin\"); a.set_text(\"5/20/2017\");";
    object a = wb.Document.InvokeScript("eval", new object[] { szJava });
    if (webDatePicker != null)
        webDatePicker.InvokeMember("submit");

    HtmlElement button = wb.Document.GetElementById("ctl00$WebSplitter1$tmpl1$ContentPlaceHolder1$HeaderBTN1$btnRetrieve");
    if (button != null)
    {
         button.InvokeMember("click");
    }
}


Robert Welliever

Это хорошо, что вы нашли свое собственное решение, но я должен был упомянуть одну вещь, чтобы, возможно, спасти вас от будущих затруднений. Вы упомянули Java дважды, но Java никогда не входит в картину. Вы пишете биты Javascript для анализа HTML-текста для создания DOM-объектов в этом коде.

Рейтинг:
0

Robert Welliever

Обыскав сотни сайтов, я мог бы не согласиться с вашей тактикой попытки использовать боты для управления страницей. Вместо этого вы можете вручную создать свой POST-запрос и соответствующим образом заполнить контент / полезную нагрузку. Например, в Google Chrome перейдите на страницу, с которой нужно запустить POST-запрос. На этой странице щелкните правой кнопкой мыши и выберите «проверить». Затем щелкните вкладку «Сеть», чтобы просмотреть все запросы. Выполните POST вручную, а затем щелкните этот запрос в появившемся списке сетевой активности. Щелкните вкладку «Заголовки» справа, чтобы увидеть все заголовки. При запросе типа POST вы увидите раздел «Данные формы». Это контент POST, который вы хотите захватить. Вы должны вставить это как шаблон в свой собственный запрос POST. Так, например, чтобы вставить свою дату в контент, ваша процедура может выглядеть примерно так:

public static HttpWebRequest CreatePOSTRequest(string url, DateTime someDate)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("someURL");
    request.Method = "POST";
    string payload = "somepastedcontent;somedatevalue=" +
                      someDate.ToString() +
                      ";somemoretemplatestuff";
    byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(payload);
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = byteArray.Length;
    using (System.IO.Stream dataStream = request.GetRequestStream())
    {
        dataStream.Write(byteArray, 0, byteArray.Length);
    }
    return request;
}

Обратите внимание, что вам нужно будет установить вышеуказанный запрос.ContentType-тип контента вашей цели, указанный в заголовках. Затем, чтобы выполнить вышеуказанный веб-запрос, вы делаете что-то вроде:
string responseText;
WebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream stream = response.GetResponseStream()) {
    using (StreamReader reader = new StreamReader(response.GetResponseStream(), 
                                                  System.Text.ASCIIEncoding.UTF8))
    {
        responseText = _ConditionResponse(reader.ReadToEnd());
    }
}


Я был бы рад оказать конкретную помощь, если вы предоставите страницу, которую хотите очистить. В противном случае удачи!


mjackson11

Сначала я попробовал этот подход. Я смог изменить данные поста, но сайт возвращается с неопределенной ошибкой. Никакого кода или объяснения. Предположение, что viewstate не соответствует сообщению, и оно вышвырнуло его. Кроме того, похоже, что они поместили на страницу какой-то генератор случайных чисел, чтобы действительно затруднить имитацию поста.

Думая, что мне, возможно, придется вручную пройти через всю java на странице и выяснить, как имитировать действия выбора даты.

Robert Welliever

У меня большой опыт работы с тем, что вы описываете, и я обещаю, что это правильное решение. Вам просто нужно захватить и разобрать страницу, необходимую для вашего поста. Какой ресурс вы пытаетесь наскрести? Если я не смогу дать вам оптимальное решение через двадцать минут после того, как прочитаю ваше сообщение, вы можете получить свои деньги обратно.