为什么我的 WebClient return 大多数时候出现 404 错误,但并非总是如此?
Why does my WebClient return a 404 error most of the time, but not always?
我想在我的程序中获取有关 Microsoft 更新的信息。但是,服务器 returns 在大约 80% 的时间出现 404 错误。我将有问题的代码归结为这个控制台应用程序:
using System;
using System.Net;
namespace WebBug
{
class Program
{
static void Main(string[] args)
{
while (true)
{
try
{
WebClient client = new WebClient();
Console.WriteLine(client.DownloadString("https://support.microsoft.com/api/content/kb/3068708"));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
}
}
}
当我 运行 代码时,我必须循环几次直到得到实际响应:
The remote server returned an error: (404) Not found.
The remote server returned an error: (404) Not found.
The remote server returned an error: (404) Not found.
<div kb-title title="Update for customer experience and diagnostic telemetry [...]
我可以根据需要在浏览器中打开并强制刷新 (Ctrl + F5) link,但它会正常显示。
问题出现在具有两个不同互联网连接的两台不同机器上。
我还使用 Html Agility Pack 测试了这种情况,但结果相同。
其他网站 不会 出现此问题。 (根 https://support.microsoft.com
在 100% 的时间里工作正常)
为什么我会得到这个奇怪的结果?
饼干。这是因为cookies。
当我开始深入研究这个问题时,我注意到我第一次在新浏览器中打开该网站时出现了 404,但在刷新(有时一次,有时几次)后该网站继续工作。
那是我搞定 Chrome 的隐身模式和开发者工具的时候。
网络没有任何可疑之处:如果您加载 http,则可以简单地重定向到 https 版本。
但我确实注意到 cookie 发生了变化。这是我第一次加载页面时看到的内容:
这是刷新(或几次)刷新后的页面:
注意到如何添加更多的 cookie 条目了吗?该站点必须尝试阅读这些内容,而不是找到它们,而 "blocking" 您。这可能是防机器人程序或糟糕的编程,我不确定。
无论如何,下面是让您的代码正常工作的方法。此示例使用 HttpWebRequest/Response,而不是 WebClient。
string url = "https://support.microsoft.com/api/content/kb/3068708";
//this holds all the cookies we need to add
//notice the values match the ones in the screenshot above
CookieContainer cookieJar = new CookieContainer();
cookieJar.Add(new Cookie("SMCsiteDir", "ltr", "/", ".support.microsoft.com"));
cookieJar.Add(new Cookie("SMCsiteLang", "en-US", "/", ".support.microsoft.com"));
cookieJar.Add(new Cookie("smc_f", "upr", "/", ".support.microsoft.com"));
cookieJar.Add(new Cookie("smcexpsessionticket", "100", "/", ".microsoft.com"));
cookieJar.Add(new Cookie("smcexpticket", "100", "/", ".microsoft.com"));
cookieJar.Add(new Cookie("smcflighting", "wwp", "/", ".microsoft.com"));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
//attach the cookie container
request.CookieContainer = cookieJar;
//and now go to the internet, fetching back the contents
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using(StreamReader sr = new StreamReader(response.GetResponseStream()))
{
string site = sr.ReadToEnd();
}
如果您删除 request.CookieContainer = cookieJar;
,它将失败并显示 404,这会重现您的问题。
代码示例的大部分工作来自 this post and this post。
我想在我的程序中获取有关 Microsoft 更新的信息。但是,服务器 returns 在大约 80% 的时间出现 404 错误。我将有问题的代码归结为这个控制台应用程序:
using System;
using System.Net;
namespace WebBug
{
class Program
{
static void Main(string[] args)
{
while (true)
{
try
{
WebClient client = new WebClient();
Console.WriteLine(client.DownloadString("https://support.microsoft.com/api/content/kb/3068708"));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
}
}
}
当我 运行 代码时,我必须循环几次直到得到实际响应:
The remote server returned an error: (404) Not found.
The remote server returned an error: (404) Not found.
The remote server returned an error: (404) Not found.
<div kb-title title="Update for customer experience and diagnostic telemetry [...]
我可以根据需要在浏览器中打开并强制刷新 (Ctrl + F5) link,但它会正常显示。
问题出现在具有两个不同互联网连接的两台不同机器上。
我还使用 Html Agility Pack 测试了这种情况,但结果相同。
其他网站 不会 出现此问题。 (根 https://support.microsoft.com
在 100% 的时间里工作正常)
为什么我会得到这个奇怪的结果?
饼干。这是因为cookies。
当我开始深入研究这个问题时,我注意到我第一次在新浏览器中打开该网站时出现了 404,但在刷新(有时一次,有时几次)后该网站继续工作。
那是我搞定 Chrome 的隐身模式和开发者工具的时候。
网络没有任何可疑之处:如果您加载 http,则可以简单地重定向到 https 版本。
但我确实注意到 cookie 发生了变化。这是我第一次加载页面时看到的内容:
这是刷新(或几次)刷新后的页面:
注意到如何添加更多的 cookie 条目了吗?该站点必须尝试阅读这些内容,而不是找到它们,而 "blocking" 您。这可能是防机器人程序或糟糕的编程,我不确定。
无论如何,下面是让您的代码正常工作的方法。此示例使用 HttpWebRequest/Response,而不是 WebClient。
string url = "https://support.microsoft.com/api/content/kb/3068708";
//this holds all the cookies we need to add
//notice the values match the ones in the screenshot above
CookieContainer cookieJar = new CookieContainer();
cookieJar.Add(new Cookie("SMCsiteDir", "ltr", "/", ".support.microsoft.com"));
cookieJar.Add(new Cookie("SMCsiteLang", "en-US", "/", ".support.microsoft.com"));
cookieJar.Add(new Cookie("smc_f", "upr", "/", ".support.microsoft.com"));
cookieJar.Add(new Cookie("smcexpsessionticket", "100", "/", ".microsoft.com"));
cookieJar.Add(new Cookie("smcexpticket", "100", "/", ".microsoft.com"));
cookieJar.Add(new Cookie("smcflighting", "wwp", "/", ".microsoft.com"));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
//attach the cookie container
request.CookieContainer = cookieJar;
//and now go to the internet, fetching back the contents
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using(StreamReader sr = new StreamReader(response.GetResponseStream()))
{
string site = sr.ReadToEnd();
}
如果您删除 request.CookieContainer = cookieJar;
,它将失败并显示 404,这会重现您的问题。
代码示例的大部分工作来自 this post and this post。