WebClient 仅为该网站返回 403 错误?
WebClient returning 403 error only for this website?
我正在尝试使用 C# WebClient 从这些链接下载文件,但出现 403 错误。
我尝试使用不同的用户代理、接受编码等。
我替换并尝试从 url https 到 http,但没有成功。
当我将这些 url 粘贴到 Chrome 或 FireFox 或 IE 中时,我能够下载文件,有时它会出现 403 错误,然后我将 https 替换为 http 从 url,它会下载。但是在 webclient 中没有成功
试过 Fiddler 检查,没有成功
有人可以在你的系统中试试,解决这个问题。
这是我的代码:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
WebClient client= new WebClient();
Uri request_url = new Uri("https://www.digikey.com/product-search/download.csv?FV=ffe00035&quantity=0&ColumnSort=0&page=5&pageSize=500);
//tried http also http://www.digikey.com/product-search/download.csv?FV=ffe00035&quantity=0&ColumnSort=0&page=5&pageSize=500
client.Headers.Add("user-agent", " Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
client.DownloadFile(request_url, @"E:3.csv");
我知道有很多跟这个主题相关的帖子,我都试过了,都没有成功,请不要标记重复。在您的系统中尝试这 <10 行代码。
注意:相同的代码适用于其他网站,仅此网站出错。
我用你的 URL 进行了测试,我能够重现你的错误。我尝试使用查询字符串参数 quantity=0
的任何请求似乎都失败了 HTTP Error 403
.
我建议请求 quantity
大于零。
HTTP 403 状态代码表示被禁止,因此您的凭据有问题。看来你没有发送任何东西。如果您将它们添加到您的 header 中,这应该可以正常工作:
client.Headers.Add("Authorization", "token");
或者这样发送:
client.UseDefaultCredentials = true;
client.Credentials = new NetworkCredential("username", "password");
很可能链接通过网络浏览器工作是因为您已经通过身份验证并且浏览器正在发送 credentials/token。
正如我在评论中提到的,这里的问题是服务器需要一个 cookie(特别是 'i10c.bdddb')存在,如果不存在则给出 403 错误。但是,cookie 与 403 响应一起发送。因此,您可以发出初始垃圾请求,该请求将失败但会为您提供 cookie。在此之后,您可以照常进行。
通过反复试验,我能够使用以下代码获取 CSV:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
CookieContainer cookieContainer = new CookieContainer();
Uri baseUri = new Uri("https://www.digikey.com");
using (HttpClientHandler handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (HttpClient client = new HttpClient(handler) { BaseAddress = baseUri})
{
//The User-Agent is required (what values work would need to be tested)
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0");
//Make our initial junk request that will fail but get the cookie
HttpResponseMessage getCookiesResponse = await client.GetAsync("/product-search/download.csv");
//Check if we actually got cookies
if (cookieContainer.GetCookies(baseUri).Count > 0)
{
//Try getting the data
HttpResponseMessage dataResponse = await client.GetAsync("product-search/download.csv?FV=ffe00035&quantity=0&ColumnSort=0&page=4&pageSize=500");
if(dataResponse.StatusCode == HttpStatusCode.OK)
{
Console.Write(await dataResponse.Content.ReadAsStringAsync());
}
}
else
{
throw new Exception("Failed to get cookies!");
}
}
备注
即使使用正确的 cookie,如果您不发送 User-Agent
header,服务器也会 return 403。我不确定服务器对一个用户代理,我只是复制了我的浏览器发送的值。
在检查是否已设置 cookie 时,最好验证您确实拥有 'i10c.bdddb' cookie,而不是仅仅检查是否有任何 cookie。
这只是一小部分示例代码,因此它不是最干净的。您可能需要查看 FormUrlEncodedContent
以发送页码和其他参数。
我的 Digi-key 也有这个问题。
我的解决方案是关闭我的 VPN 服务。
我正在尝试使用 C# WebClient 从这些链接下载文件,但出现 403 错误。
我尝试使用不同的用户代理、接受编码等。 我替换并尝试从 url https 到 http,但没有成功。 当我将这些 url 粘贴到 Chrome 或 FireFox 或 IE 中时,我能够下载文件,有时它会出现 403 错误,然后我将 https 替换为 http 从 url,它会下载。但是在 webclient 中没有成功 试过 Fiddler 检查,没有成功 有人可以在你的系统中试试,解决这个问题。
这是我的代码:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
WebClient client= new WebClient();
Uri request_url = new Uri("https://www.digikey.com/product-search/download.csv?FV=ffe00035&quantity=0&ColumnSort=0&page=5&pageSize=500);
//tried http also http://www.digikey.com/product-search/download.csv?FV=ffe00035&quantity=0&ColumnSort=0&page=5&pageSize=500
client.Headers.Add("user-agent", " Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
client.DownloadFile(request_url, @"E:3.csv");
我知道有很多跟这个主题相关的帖子,我都试过了,都没有成功,请不要标记重复。在您的系统中尝试这 <10 行代码。
注意:相同的代码适用于其他网站,仅此网站出错。
我用你的 URL 进行了测试,我能够重现你的错误。我尝试使用查询字符串参数 quantity=0
的任何请求似乎都失败了 HTTP Error 403
.
我建议请求 quantity
大于零。
HTTP 403 状态代码表示被禁止,因此您的凭据有问题。看来你没有发送任何东西。如果您将它们添加到您的 header 中,这应该可以正常工作:
client.Headers.Add("Authorization", "token");
或者这样发送:
client.UseDefaultCredentials = true;
client.Credentials = new NetworkCredential("username", "password");
很可能链接通过网络浏览器工作是因为您已经通过身份验证并且浏览器正在发送 credentials/token。
正如我在评论中提到的,这里的问题是服务器需要一个 cookie(特别是 'i10c.bdddb')存在,如果不存在则给出 403 错误。但是,cookie 与 403 响应一起发送。因此,您可以发出初始垃圾请求,该请求将失败但会为您提供 cookie。在此之后,您可以照常进行。
通过反复试验,我能够使用以下代码获取 CSV:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
CookieContainer cookieContainer = new CookieContainer();
Uri baseUri = new Uri("https://www.digikey.com");
using (HttpClientHandler handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (HttpClient client = new HttpClient(handler) { BaseAddress = baseUri})
{
//The User-Agent is required (what values work would need to be tested)
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0");
//Make our initial junk request that will fail but get the cookie
HttpResponseMessage getCookiesResponse = await client.GetAsync("/product-search/download.csv");
//Check if we actually got cookies
if (cookieContainer.GetCookies(baseUri).Count > 0)
{
//Try getting the data
HttpResponseMessage dataResponse = await client.GetAsync("product-search/download.csv?FV=ffe00035&quantity=0&ColumnSort=0&page=4&pageSize=500");
if(dataResponse.StatusCode == HttpStatusCode.OK)
{
Console.Write(await dataResponse.Content.ReadAsStringAsync());
}
}
else
{
throw new Exception("Failed to get cookies!");
}
}
备注
即使使用正确的 cookie,如果您不发送 User-Agent
header,服务器也会 return 403。我不确定服务器对一个用户代理,我只是复制了我的浏览器发送的值。
在检查是否已设置 cookie 时,最好验证您确实拥有 'i10c.bdddb' cookie,而不是仅仅检查是否有任何 cookie。
这只是一小部分示例代码,因此它不是最干净的。您可能需要查看 FormUrlEncodedContent
以发送页码和其他参数。
我的 Digi-key 也有这个问题。
我的解决方案是关闭我的 VPN 服务。