HttpWebRequest: Как найти почтовый индекс в Canada Post через WebRequest с приложением x-www-form?

В настоящее время я пишу несколько тестов, чтобы улучшить свои навыки взаимодействия с Интернетом через Windows Forms. Одним из таких тестов является поиск почтового индекса, который должен быть возвращен веб-сайтом Canada Post.

  1. Моя настройка URL по умолчанию: http://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity?execution=e4s1
  2. Обязательные поля формы: streetNumber, streetName, город, провинция
  3. 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);

Некоторые проблемы, которые я обнаружил в вашем оригинальном коде:-

  1. В первом поле стоит префикс &, которого там быть не должно.
  2. Вам нужно использовать вызов Uri.EscapeDataString на каждое значение поля.
  3. Вы пытаетесь построить поток памяти вокруг результата 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 в ответ на ваш запрос. В противном случае вы можете проанализировать вывод запроса.

Другие вопросы по тегам