HttpWebRequest返回“(403)Forbidden”错误

我写了一个xml抓取器来接收/解码网站上的xml文件。 它主要工作正常,但它总是返回错误:

“远程服务器返回错误:(403)禁止。”

网站http://w1.weather.gov/xml/current_obs/KSRQ.xml

我的代码是:

CookieContainer cookies = new CookieContainer(); HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(Path); webRequest.Method = "GET"; webRequest.CookieContainer = cookies; using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()) { using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream())) { string xml = streamReader.ReadToEnd(); xmldoc.LoadXml(xml); } } 

抛出GetResponse方法就是例外。 我怎么知道发生了什么?

可能是您的请求缺少服务器所需的标头。 我在浏览器中请求了该页面,使用Fiddler记录了确切的请求,然后删除了User-Agent标头并重新发出了请求。 这导致了403响应。

这通常被服务器用来试图阻止他们的站点编写脚本,就像你正在做的那样; o)

在这种情况下,403响应中的服务器头是“AkamaiGHost”,它表示来自Akamai的某些云安全解决方案的边缘节点。 也许用于防止机器人的WAF规则正在触发403。

似乎向User-Agent标头添加任何值都适用于此站点。 例如,我把它设置为“绝对不是一个屏幕刮板”,这似乎工作正常。

通常,当您遇到此类问题时,使用浏览器工具或Fiddler等代理查看实际的HTTP请求和响应通常会有所帮助。 正如Scott Hanselman所说

互联网不是黑匣子

http://www.hanselman.com/blog/TheInternetIsNotABlackBoxLookInside.aspx

显然,URL可以在浏览器中运行。 它只是从代码中无效。 看起来服务器正在接受/拒绝基于用户代理的请求,这可能是尝试阻止爬虫的一种非常基本的方式。

要通过,只需将UserAgent属性设置为它将识别的内容,例如:

 webRequest.UserAgent = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36"; 

这确实有效。

您的请求是通过代理服务器进行的吗? 如果是,请在GetResponse()调用之前添加以下行。

 webRequest.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials; 

您很可能无权访问您尝试访问的资源。 因此,您需要获取必要的凭据才能完成所需的操作。

在我的特定情况下,它不是UserAgent标头,而是服务器不喜欢的Accept标头。

 request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"; 

您可以使用开发工具的浏览器网络选项卡查看正确的标头应该是什么。