记一次http下载0KB问题的解决
最近在写C#,.net的一个下载程序,用到了网络下载(其他语言也别一下就走开,问题和解题思路是相同的,不妨花2min看一下)。发现一个问题:
某个链接,明明是下载地址,比如有人给我反馈这个链接 http://wowui.178.com/down/337/13178/Outfitter-5.22_.1_.zip,
无法下载。而在页面上的按钮,点击就可以下载?!
对于.net的下载方法,主要有2个,一个是WebClient,一个是HttpWebRequest。
而HttpWebRequest其实各个其他语言平台都存在的标准的http请求方式,可以给他的对象进行设置Accept,Cookies,Refer等等。
首先想到的是,自己手里的下载方法不够强大,于是github和baidu都找了很多框架和helper类,未果;
经过1天的挣扎,发现一个现象,复制该链接到浏览器的网址搜索栏中回车,也是跳转了网页,并没有直接弹出下载;而点击页面中下载按钮就是直接下载!并且通过查看元素代码,并没有做什么额外的js解析,变换下载什么的。
接下来,关键的,通过浏览器的开发者工具,network页面。
当我复制到搜索栏的时候,出现如下2张图的标头:
而且当我们点击下载按钮的时候,出现如下标头(其实也跟上面一样有2张,还有一张跟上面一样是错误的,这里就不贴上来了):
可以看到,错误的请求,跟正确的下载请求标头的差异是只有一个:
Refer没有配置!
于是修改代码尝试(逐个逐个额外添加):
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Accept = "*/*";//添加Accept
request.UserAgent = @"User - Agent: Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 64.0.3282.140 Safari / 537.36 Edge / 17.17134"; //添加UA
request.CookieContainer = new CookieContainer(); //添加cookies
if(refer != null) request.Referer = refer; //添加refer
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
Stream responseStream = response.GetResponseStream();
...
所以,总结来说,当我们使用http下载的时候,需要注意几个点:
- 我们经常需要给请求,添加UA或者Cookies,否则容易被当做爬虫而拒绝;
- Accept在某种特定可能有问题;
- 像这种特殊的下载失败0KB问题或者一些crash Exception,我们需要进一步分析跟浏览器的请求差异,分析差别在哪里。找出原因。