为什么我的WebClient大部分时间都会返回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%正常工作)
为什么我得到这个奇怪的结果?
cookies。 这是因为cookies。
当我开始深入研究这个问题时,我注意到我第一次在新的浏览器中打开网站时得到了404,但在刷新后(有时一次,有时几次)网站继续工作。
那是我淘汰Chrome的Incognito模式和开发者工具的时候。
网络上没有任何可疑之处:如果您加载了http,则会有一个简单的重定向到https版本。
但我注意到的是cookies改变了。 这是我第一次加载页面时看到的内容:
这是(或几个)刷新后的页面:
请注意如何添加更多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,再现您的问题。
代码示例的大部分内容都来自这篇文章和这篇文章 。