WebRequest / POST вопрос о извлечении конкретных данных с веб-сайта - PullRequest
0 голосов
/ 16 марта 2011

Я пытаюсь собрать данные о конкретных событиях с веб-сайта компании: http://pipeline.kindermorgan.com/infoposting/notices.aspx?type=CRIT Я работал со многими подобными сайтами, но до сих пор они были довольно простыми, и это просто вопрос перехода на сайт и работы с потоком ответов. В этом случае веб-сайт требует, чтобы вы выбрали значение из первого поля со списком (Имя TSP / TSP). Без передачи какой-либо информации, URL вернет данные, связанные с первым элементом в списке. Мне действительно нужно иметь возможность получить данные, связанные с любым из элементов в списке.

Вот код, который я использовал до сих пор, но он не работает с ошибкой сервера 500, поэтому я предполагаю, что либо я не правильно сформировал POST, либо пропускаю некоторые данные в данных поста):

Для страницы, которую я перечислил выше, я просто хочу получить поток ответов с таблицей уведомлений для конкретного TSP из поля со списком (начиная с Trailblazer). Я знаю, что элемент управления - «ctl00 $ ContentPlaceHolder1 $ ddlpipeline», и значение, которое я хочу отправить, - 24. Когда я перехожу через IE, мне также нужно нажать кнопку «Получить».

Когда я смотрю на запрос POST с использованием FireBug, я замечаю, что в него включено много других целей / значений. Я не уверен, нужно ли мне отправлять все эти сообщения, и (я никогда раньше не делал POST), я не уверен, как отформатировать данные в POST, чтобы сделать это.

Потерпи меня, если этот запрос кажется странным. Я больше работаю в базе данных и хочу автоматизировать многие вещи, которые мы должны рассматривать вручную каждый день. Любая помощь будет принята с благодарностью!

    var encoding = new ASCIIEncoding(); 

    var postData = "ctl00$ContentPlaceHolder1$ddlpipeline=24";

    byte[] data = encoding.GetBytes(postData);

    string RemoteURI = "http://pipeline.kindermorgan.com/infoposting/notices.aspx?type=CRIT";

    var myRequest = (HttpWebRequest)WebRequest.Create(RemoteURI);

    myRequest.Method = "POST";

    myRequest.ContentType = "application/x-www-form-urlencoded";

    myRequest.ContentLength = data.Length;

    var newStream = myRequest.GetRequestStream();

    newStream.Write(data, 0, data.Length);

    newStream.Close();

    var response = myRequest.GetResponse();

    var responseStream = response.GetResponseStream();

    var responseReader = new StreamReader(responseStream);

1 Ответ

0 голосов
/ 19 марта 2011

Я на самом деле решил проблему, и я обнаружил в процессе несколько вещей, которыми я поделюсь с другими, которые могут посмотреть эту ветку.

Во-первых, мне пришлось построить данные POST в точности так, как они отображаются в POST в браузере (я использовал Firebug для просмотра данных POST). Это также означало получение скрытых аргументов (особенно VIEWSTATE и EVENTVALIDATION). Я смог получить их, просто загрузив исходный код страницы по умолчанию (кстати, я делаю это в коде, потому что он не статичен для этого сайта) и проанализировав значения для скрытых полей. Затем я строю строку данных POST с любыми возможными изменениями (в моем случае изменение даты было важным, но в будущем я могу изменить другие вещи).

Теперь то, что действительно меня озадачило. Я подтвердил, что строка данных POST была точно такой же, как и строка, отправленная FireFox / FireBug через символьное сравнение, и все равно не будет работать. Затем я вспомнил в предыдущем случае, что мне нужно было установить пользовательский агент.

Итак, вот код, с которым я закончил:

string postData = String.Format("__EVENTTARGET=&__EVENTARGUMENT=&__LASTFOCUS="
    + "&__VIEWSTATE={0}"
    + "&ctl00%24UltraWebTree1={1}"
    + "&ctl00%24ContentPlaceHolder1%24ddlNoticeCategory={2}"
    + "&ctl00%24ContentPlaceHolder1%24ddlpipeline={3}"
    + "&ctl00%24ContentPlaceHolder1%24Button1={4}"
    + "&ctl00%24ContentPlaceHolder1%24tbDate={5}"
    + "&ctl00%24ContentPlaceHolder1%24ddlNoticeType={6}"
    + "&ctl00%24ContentPlaceHolder1%24tbSubject={7}"
    + "&ctl00%24ContentPlaceHolder1%24ddlNoticeSubType={8}"
    + "&ctl00%24ContentPlaceHolder1%24ddlOrderBy={9}"
    + "&ctl00%24ContentPlaceHolder1%24hfmode={10}"
    + "&ctl00%24ContentPlaceHolder1%24hfODSCommand={11}&ctl00%24hfPipeline={12}"
    + "&__PREVIOUSPAGE={13}&__EVENTVALIDATION={14}",
    viewstate, webtree, noticecategory, pplcode, 
    button1, todaydate, noticetype, subject, 
    noticesubtype, orderby, hfmode, hfODSCommand, 
    hfPipeline, previouspage, eventvalidation);

var encoding = new ASCIIEncoding(); 
byte[] data = encoding.GetBytes(postData);

var myRequest = (HttpWebRequest)WebRequest.Create(RemoteURI); 
myRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)" ;
myRequest.Method = "POST" ;
myRequest.ContentType = "application/x-www-form-urlencoded";
myRequest.ContentLength = data.Length;

var newStream = myRequest.GetRequestStream(); 
newStream.Write(data, 0, data.Length);
newStream.Close();

var myresponse = myRequest.GetResponse(); 
var responseStream = myresponse.GetResponseStream(); 
var responseReader = new StreamReader(responseStream); 
string webpagesource = responseReader.ReadToEnd();

Надеюсь, это поможет кому-то еще.

...