为什么我的WebClient大部分时间都会返回404错误,但并非总是如此?

时间:2015-07-10 19:00:52

标签: c# web http-status-code-404

我想在我的程序中获取有关Microsoft Update的信息。但是,服务器在大约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();
            }
        }
    }
}

当我运行代码时,我必须经历几次循环,直到得到实际响应:

  

远程服务器返回错误:(404)未找到。
  远程服务器返回错误:(404)未找到。
  远程服务器返回错误:(404)未找到。
  < div kb-title title =“客户体验和诊断遥测的更新[...]

我可以随时打开并强制刷新(Ctrl + F5)我浏览器中的链接,但它会显示正常。

问题出现在具有两个不同互联网连接的两台不同机器上 我也使用Html Agility Pack测试了这个案例,但结果相同。
其他网站出现问题。 (根https://support.microsoft.com在100%的时间内都能正常工作)

为什么我会得到这个奇怪的结果?

1 个答案:

答案 0 :(得分:5)

缓存数据。这是因为cookies。

当我开始深入研究这个问题时,我注意到我第一次在新的浏览器中打开网站时得到了404,但在刷新后(有时一次,有时几次)网站继续工作。

当我破坏了Chrome的隐身模式和开发者工具时。

网络上没有任何可疑之处:如果您加载了http,则会有一个简单的重定向到https版本。

但我注意到的是饼干改变了。这是我第一次加载页面时看到的内容:

enter image description here

以及(或几个)刷新后的页面:

enter image description here

请注意如何添加更多Cookie条目?该网站必须试图阅读那些,而不是找到它们,并且"阻止"您。这可能是机器人预防设备或糟糕的编程,我不确定。

无论如何,这里是如何使你的代码工作的。此示例使用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 postthis post