WebRequest:如何使用针对此ContentType的WebRequest查找邮政编码=“application / xhtml + xml,text / xml,text / html; 字符集= UTF-8” ?

我首先发布了这个: HttpWebRequest:如何通过带有x-www-form-enclosed的WebRequest在Canada Post找到邮政编码? 。

根据AnthonyWJones的建议,我根据他的建议改变了我的代码。

继续我的询问,我已经注意到加拿大邮政的内容类型更可能是“application / xhtml + xml,text / xml,text / html; charset = utf-8”

我的问题是:

  1. 我们如何针对这样的内容类型网站进行webrequest?
  2. 我们是否必须继续使用NameValueCollection对象?
  3. 根据Scott Lance在我之前的问题中慷慨地向我提供了宝贵的信息,WebRequest应该返回任何内容类型的信息类型,我在这里遗漏了什么?
  4. 由于内容类型的变化,我是否必须更改我的代码?

这是我的代码,以便更容易理解我的进度。

internal class PostalServicesFactory { ///  /// Initializes an instance of GI.BusinessSolutions.Services.PostalServices.Types.PostalServicesFactory class. ///  internal PostalServicesFactory() { } ///  /// Finds a Canadian postal code for the provided Canadian address. ///  /// The instance of GI.BusinessSolutions.Services.PostalServices.ICanadianCityAddress for which to find the postal code. /// The postal code found, otherwise null. internal string FindPostalCode(ICanadianCityAddress address) { if (address == null) throw new InvalidOperationException("No valid address specified."); using (ServicesWebClient swc = new ServicesWebClient()) { var values = new System.Collections.Specialized.NameValueCollection(); values.Add("streetNumber", address.StreetNumber.ToString()); values.Add("numberSuffix", address.NumberSuffix); values.Add("suite", address.Suite); values.Add("streetName", address.StreetName); values.Add("streetDirection", address.StreetDirection); values.Add("city", address.City); values.Add("province", address.Province); byte[] resultData = swc.UploadValues(@"http://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity", "POST", values); return Encoding.UTF8.GetString(resultData); } } private class ServicesWebClient : WebClient { public ServicesWebClient() : base() { } protected override WebRequest GetWebRequest(Uri address) { var request = (HttpWebRequest)base.GetWebRequest(address); request.CookieContainer = new CookieContainer(); return request; } } } 

此代码实际上返回了必须填写所需信息的表单的HTML源代码,以便使用邮政编码搜索进行处理。 我希望通过找到的邮政编码获取HTML源代码或其他任何内容。

编辑:这是我现在得到的WebException:“无法发送带有此类动词的内容正文。” (这是法国例外情况的翻译“Impossible d’envoyer un corps de contenu avec ce type de verbe。”)

这是我的代码:

  internal string FindPostalCode(string url, ICanadianAddress address) { string htmlResult = null; using (var swc = new ServiceWebClient()) { var values = new System.Collections.Specialized.NameValueCollection(); values.Add("streetNumber", address.StreetNumber.ToString()); values.Add("numberSuffix", address.NumberSuffix); values.Add("suite", address.Suite); values.Add("streetName", address.StreetName); values.Add("streetDirection", address.StreetDirection); values.Add("city", address.City); values.Add("province", address.Province); swc.UploadValues(url, @"POST", values); string redirectUrl = swc.ResponseHeaders.GetValues(@"Location")[0]; => swc.UploadValues(redirectUrl, @"GET", values); } return htmlResult; } 

导致exception的行用“=>”表示。 看来我不能用GET作为方法,但这就是告诉我的事情……

知道我在这里缺少什么吗? 我试着做Justin(见答案)推荐我做的事情。

在此先感谢您的帮助! 🙂

作为对屏幕抓取世界的介绍,你选择了一个非常难的案例! 加拿大邮政的查询页面的工作方式如下:

  1. 第一页是接受地址值的表单
  2. 此页面发布到第二个URL。
  3. 第二个URL依次重定向(使用HTTP 302重定向)到第三个URL,实际显示包含邮政编码的HTML响应。

更糟糕的是,步骤#3中的页面需要知道步骤#1中设置的cookie。 因此,您需要为所有三个请求使用相同的CookieContainer (尽管将相同的CookieContainer发送到#2和#3可能就足够了)。

此外,您可能还需要在这些请求中发送其他HTTP标头,例如Accept。 我怀疑你遇到问题的地方是HttpWebRequest默认为你透明地处理重定向 – 但是当它透明地重定向时,它可能无法添加模拟浏览器所需的正确HTTP头。

解决方案是将HttpWebRequestAllowAutoRedirect属性设置为false,并AllowAutoRedirect处理重定向。 换句话说,一旦第一个请求返回重定向,您就需要在HttpWebResponseLocation:头中提取URL。 然后,您需要为该URL创建一个新的HttpWebRequest (这次是常规GET请求,而不是POST)。 记得发送相同的cookie! ( CookieContainer类使这很容易)

您还可能需要另外请求(上面列表中的#1)才能设置会话cookie。 如果我是你,我认为这是必需的,只是为了消除它作为一个问题,并尝试删除该步骤,看看你的解决方案是否仍然有效。

您需要下载并使用Fiddler( http://www.fiddlertool.com )来帮助您完成所有这些工作。 Fiddler允许您通过网络查看HTTP请求,并允许您(通过请求构建器function)允许您创建HTTP请求,以便您可以查看实际需要哪些标头。