【问题标题】:Why does my WebClient return a 404 error most of the time, but not always?为什么我的 WebClient 大多数时候都会返回 404 错误,但并非总是如此?
【发布时间】:2015-07-10 19:00:51
【问题描述】:

我想在我的程序中获取有关 Microsoft 更新的信息。但是,服务器在大约 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) Not found.
远程服务器返回错误:(404) Not found.

  • 我猜是网络连接问题...
  • @PranayRana 正如我所写,我在具有不同 ISP 的两台不同机器上测试了这种行为。 并且: 结果不是简单的连接错误,我从 Microsoft IIS 服务器(这是默认的 404 模板)获得了一个实际网页。其他网站不会出现此问题。
  • 我也能重现这个。我最好的猜测是用户代理字符串(或类似字符串),微软给你一个 404,这样机器人就不会连接。我会研究这个。
  • 我已经在浏览器上尝试了该 URL,但得到了 404,因此它可能与浏览器与自定义应用程序无关。
  • 我可以重现相同的行为:控制台应用程序在 80% 的情况下返回 404(我认为甚至更高)并且浏览器 (Chrome) 没有问题。但是,VisualStudio 的“内部浏览器”(当您按住 CTRL 并单击代码中的 URL 时会打开)给出相同的结果:80% 的案例 404。

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


【解决方案1】:

饼干。这是因为 cookie。

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

就在那时,我打破了 Chrome 的隐身模式和开发者工具。

网络没有什么太可疑的地方:如果你加载了 http,就会有一个简单的重定向到 https 版本。

但我注意到的是 cookie 发生了变化。这是我第一次加载页面时看到的:

这是刷新一次(或几次)后的页面:

注意如何添加了更多 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

【讨论】:

  • 干得好。 +1 用于研究、解释和解决方案。
  • 惊人的研究,完美无瑕。 async TryGetKBArticle()再见。 :)
猜你喜欢
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
  • 2010-10-30
  • 2012-10-26
  • 2017-12-11
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
相关资源
最近更新 更多