HttpWebRequest: Как найти почтовый индекс в Canada Post через WebRequest с приложением x-www-form?
В настоящее время я пишу несколько тестов, чтобы улучшить свои навыки взаимодействия с Интернетом через Windows Forms. Одним из таких тестов является поиск почтового индекса, который должен быть возвращен веб-сайтом Canada Post.
- Моя настройка URL по умолчанию: http://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity?execution=e4s1
- Обязательные поля формы: streetNumber, streetName, город, провинция
- ContentType является "application/x-www-form-closed"
РЕДАКТИРОВАТЬ: Пожалуйста, рассмотрите значение "application/x-www-form-encoded" вместо значения пункта 3 как contentType. (Спасибо EricLaw-MSFT!)
Результат, который я получаю, не является ожидаемым результатом. Я получаю исходный код HTML страницы, где я могу вручную ввести информацию, чтобы найти почтовый индекс, но не исходный код HTML с найденным почтовым индексом. Есть идеи, что я делаю не так?
Должен ли я пойти по пути XML? Можно ли в первую очередь осуществлять поиск на канадской почте анонимно?
Вот пример кода для лучшего описания:
public static string FindPostalCode(ICanadadianAddress address) {
var postData = string.Concat(string.Format("&streetNumber={0}", address.StreetNumber)
, string.Format("&streetName={0}", address.StreetName)
, string.Format("&city={0}", address.City)
, string.Format("&province={0}", address.Province));
var encoding = new ASCIIEncoding();
byte[] postDataBytes = encoding.GetBytes(postData);
request = (HttpWebRequest)WebRequest.Create(DefaultUrlSettings);
request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Anonymous;
request.Container = new CookieContainer();
request.Timeout = 10000;
request.ContentType = contentType;
request.ContentLength = postDataBytes.LongLength;
request.Method = @"post";
var senderStream = new StreamWriter(request.GetRequestStream());
senderStream.Write(postDataBytes, 0, postDataBytes.Length);
senderStream.Close();
string htmlResponse = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
return processedResult(htmlResponse); // Processing the HTML source code parsing, etc.
}
Я, кажется, застрял в горлышке бутылки с моей точки зрения. Я не нахожу выхода к желаемому результату.
РЕДАКТИРОВАТЬ: Кажется, есть параметры, как для ContentType этого сайта. Позволь мне объяснить.
- Есть один с мета-переменными, который предусматривает следующее:
meta http-equ ="Content-Type" content="application/xhtml+xml, text/xml, text/html; charset=utf-8"
- И еще один позже код, который читается как:
form id = "fpcByAdvancedSearch: fpcSearch" name = "fpcByAdvancedSearch: fpcSearch" method = "post" action = "/ cpotools / apps / fpc / personal / findByCity? execute =e1s1" enctype="application/x-www-form-urco "
Мой вопрос заключается в следующем: с какой я должен придерживаться?
Позвольте мне предположить, первый ContentType должен рассматриваться как второй только для другого запроса к функции или около того, когда данные публикуются?
РЕДАКТИРОВАТЬ: В соответствии с запросом, ближе к решению, которое я нахожусь в списке под этим вопросом: WebRequest: Как найти почтовый код, используя WebRequest для этого ContentType = ”application / xhtml + xml, text / xml, text / html; кодировка = UTF-8”?
Спасибо за любую помощь!:-)
2 ответа
Я пытаюсь понять причину, по которой вы не используете класс WebClient:
var fields = new NameValueCollection();
fields.Add("streetnumber", address.StreetNumber);
fields.Add("streetname", address.StreetName);
fields.Add("city", address.City);
fields.Add("province", address.Province);
var wc = new WebClient();
byte[] resultData = wc.UploadValues(url, fields);
string result = Encoding.Default.GetString(resultData);
Возможно, вы захотите проверить кодировку, используемую сервером при отправке результатов, если он использует UTF-8, измените последнюю строку на:-
string result = Encoding.UTF8.GetString(resultData);
Некоторые проблемы, которые я обнаружил в вашем оригинальном коде:-
- В первом поле стоит префикс &, которого там быть не должно.
- Вам нужно использовать вызов
Uri.EscapeDataString
на каждое значение поля. - Вы пытаетесь построить поток памяти вокруг результата
GetRequestStream
Я не вижу, чего бы это достигло, даже еслиMemoryStream
был такой конструктор, но это не так в любом случае. Просто напишите прямо в поток, возвращенныйGetRequestStream
Если вы уже сделали это, получите себе копию fiddler, чтобы вы могли наблюдать, что происходит, когда стандартная форма успешно запрашивает данные, и что делает ваш код.
Изменить: Если у вас есть доказательства того, что отсутствие контейнера cookie является причиной того, что WebClient не работает, то вы можете попробовать этот подход:-
public class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest (Uri address)
{
WebRequest request = (WebRequest) base.GetWebRequest (address);
request.Container = new CookieContainer();
return request;
}
}
Теперь используйте мой код выше, но вместо этого WebClient
пример MyWebClient
вместо.
HTTPWebRequest вернет содержимое URL-запроса. Если это HTML-страница, она вернет HTML-разметку. Если содержимое страницы является XML, то оно вернет разметку XML.
Похоже, вам нужен веб-сервис. Я бы посмотрел, есть ли на этом сайте какие-либо веб-версии для обработки запросов такого типа. Если они это сделают, то он вернет XML, разметку JSON в ответ на ваш запрос. В противном случае вы можете проанализировать вывод запроса.