gpt4 book ai didi

c# - WebRequest:如何使用针对此 ContentType ="application/xhtml+xml, text/xml, text/html; charset=utf-8"的 WebRequest 查找邮政编码?

转载 作者:行者123 更新时间:2023-11-30 17:24:06 26 4
gpt4 key购买 nike

我首先发布了这个:HttpWebRequest: How to find a postal code at Canada Post through a WebRequest with x-www-form-enclosed?

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

在我继续询问的过程中,我注意到随着时间的推移,加拿大邮政的内容类型更有可能是 "application/xhtml+xml, text/xml, text/html; charset=utf- 8".

我的问题是:

  1. 我们如何针对此类内容类型网站进行网络请求?
  2. 我们必须继续使用 NameValueCollection 对象吗?
  3. 根据 Scott Lance 在我之前的问题中慷慨地向我提供了宝贵信息的说法,WebRequest 应返回信息类型,无论内容类型是什么,我是否遗漏了什么?
  4. 我是否必须因为内容类型的变化而更改我的代码?

这是我的代码,这样可能更容易理解我的进度。

internal class PostalServicesFactory {
/// <summary>
/// Initializes an instance of GI.BusinessSolutions.Services.PostalServices.Types.PostalServicesFactory class.
/// </summary>
internal PostalServicesFactory() {
}
/// <summary>
/// Finds a Canadian postal code for the provided Canadian address.
/// </summary>
/// <param name="address">The instance of GI.BusinessSolutions.Services.PostalServices.ICanadianCityAddress for which to find the postal code.</param>
/// <returns>The postal code found, otherwise null.</returns>
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 源代码或与找到的邮政编码相关的任何内容。

EDIT: Here's the WebException I get now: "Unable to send a content body with this type of verb." (This is a translation from the French exception "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;
}

导致异常的行用“=>”指向。似乎我不能使用 GET 作为方法,但这是告诉我要做的...

知道我在这里缺少什么吗?我尝试按照贾斯汀(查看答案)推荐我去做。

在此先感谢您的帮助! :-)

最佳答案

作为屏幕抓取世界的介绍,您选择了一个非常困难的案例!加拿大邮政的查找页面是这样工作的:

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

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

此外,您可能还需要在这些请求中发送额外的 HTTP header ,例如接受。我怀疑您遇到问题的地方是 HttpWebRequest 默认情况下会为您透明地处理重定向——但是当它透明地重定向时,它可能不会添加模拟浏览器所需的正确 HTTP header 。

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

为了设置 session cookie,您可能还需要提出一个额外的请求(我上面列表中的第一个)。如果我是你,我会假设这是必需的,只是为了将其作为一个问题来消除,并稍后尝试删除该步骤,看看你的解决方案是否仍然有效。

您需要下载并使用 Fiddler (www.fiddlertool.com) 来帮助您完成这一切。 Fiddler 允许您观察通过线路传输的 HTTP 请求,并允许您(通过请求构建器功能)允许您创建 HTTP 请求,以便您可以查看实际需要哪些 header 。

关于c# - WebRequest:如何使用针对此 ContentType ="application/xhtml+xml, text/xml, text/html; charset=utf-8"的 WebRequest 查找邮政编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1455567/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com