Запрос HttpWebRequest:Как узнать почтовый индекс в Canada Post с помощью веб-запроса с приложенной x-www-формой?

StackOverflow https://stackoverflow.com/questions/1444563

Вопрос

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

  1. Мой URL-адрес по умолчанию установлен на: http://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity?execution=e4s1
  2. Обязательными полями формы являются: Номер улицы, Название улицы, город, провинция
  3. Тип содержимого - "приложение/x-www-form-enclosed".

Редактировать: Пожалуйста, используйте значение "application/x-www-form-encoded" вместо значения пункта 3 в качестве ContentType.(Спасибо EricLaw-MSFT!)

Результат, который я получаю, не соответствует ожидаемому.Я получаю исходный HTML-код страницы, где я мог бы вручную ввести информацию, чтобы найти почтовый индекс, но не исходный HTML-код с найденным почтовым индексом.Есть какие-нибудь идеи о том, что я делаю не так?

Должен ли я рассмотреть возможность перехода по пути XML?Прежде всего, возможно ли осуществлять поиск на Canada Post анонимно?

Вот пример кода для лучшего описания:

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-equiv="Content-Type" content="приложение/xhtml+xml, текст/xml, текст/html;кодировка=utf-8"

  • И еще один ниже по коду, который читается как:

идентификатор формы="fpcByAdvancedSearch: fpcSearch" name="fpcByAdvancedSearch: fpcSearch" method="опубликовать" action="/cpotools/apps/fpc/personal/findByCity?execution=e1s1" enctype="приложение/x-www-форма-urlencoded"

Мой вопрос заключается в следующем:Какого из них я должен придерживаться?

Позвольте мне угадать, первый ContentType следует рассматривать, поскольку второй предназначен только для другого запроса к функции или около того при публикации данных?

Редактировать: Согласно запросу, чем ближе я к решению, тем ниже указан этот вопрос: Веб-запрос:Как найти почтовый индекс, используя веб-запрос по этому ContentType=”application/xhtml+xml, text /xml, текст / html;кодировка=utf-8”?

Спасибо за любую помощь!:-)

Это было полезно?

Решение

Я пытаюсь понять причину, по которой вы не используете класс 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

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

Редактировать:Если у вас есть доказательства того, что отсутствие контейнера для файлов 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 в ответ на ваш запрос.В противном случае вам остается проанализировать выходные данные запроса.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top