之前用c#编写过一个处理图像的api接口,需要开始的时候将远程图片抓取到本地再进行下一步操作。本来这个从远程抓取图片的功能一直都是好用的,结果这两天从本人的另一个django网站中读取图片遇到了麻烦。虽然这个问题很容易解决,但是足足用了我两天时间才解决。废话不多说,先上c#抓取图片的代码:
参数为远程图片url和本地存放的地址(savePath)。
public bool downloadFile(string url, string savePath) ? ? ? ? { ? ? ? ? ? ? HttpWebRequest req = null; HttpWebResponse res = null; ? ? ? ? ? ? System.IO.Stream stream = null; ? ? ? ? ? ? bool result = false; System.GC.Collect(); ? ? ? ? ? ? try ? ? ? ? ? ? { ? ? ? ? ? ? ? ? req = HttpWebRequest.Create(url) as System.Net.HttpWebRequest; ? ? ? ? ? ? ? ? req.CookieContainer = new CookieContainer(); ? ? ? ? ? ? ? ? req.AllowAutoRedirect = true; ? ? ? ? ? ? ? ? req.KeepAlive = false; ? ? ? ? ? ? ? ? req.Timeout = 60 * 1000; req.ServicePoint.ConnectionLeaseTimeout = 2 * 60 * 1000; ? ? ? ? ? ? ? ? // req.ServicePoint.ConnectionLimit = int.MaxValue; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";? ? ? ? ? ? ? ? ? req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"; ? ? ? ? ? ? ? ? req.Headers.Add("Accept-Language", "en-us,en;q=0.5"); ? ? ? ? ? ? ? ? req.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7"); ? ? ? ? ? ? ? ? req.Headers.Add("Accept-Encoding", "gzip, deflate"); ? ? ? ? ? ? ? ? res = req.GetResponse() as System.Net.HttpWebResponse; ? ? ? ? ? ? ? ? stream = res.GetResponseStream(); ? ? ? ? ? ? ? ? byte[] buffer = new byte[1 * 1024]; ? ? ? ? ? ? ? ? int bytesProcessed = 0; ? ? ? ? ? ? ? ? // string filename = DateTime.Now.ToFileTime().ToString(); ? ? ? ? ? ? ? ? System.IO.FileStream fs = new FileStream(savePath, FileMode.Create, FileAccess.Write); ? ? ? ? ? ? ? ? int bytesRead; ? ? ? ? ? ? ? ? do ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? bytesRead = stream.Read(buffer, 0, buffer.Length); ? ? ? ? ? ? ? ? ? ? fs.Write(buffer, 0, bytesRead); ? ? ? ? ? ? ? ? ? ? bytesProcessed += bytesRead; ? ? ? ? ? ? ? ? } while (bytesRead > 0);
? ? ? ? ? ? ? ? fs.Flush(); ? ? ? ? ? ? ? ? fs.Close(); ? ? ? ? ? ? ? ? result = true; ? ? ? ? ? ? ? ? // fileSize = bytesProcessed; ? ? ? ? ? ? } ? ? ? ? ? ? catch ? ? ? ? ? ? { ? ? ? ? ? ? ? ? // ?ex = exception; ? ? ? ? ? ? ? ? result = false; ? ? ? ? ? ? } ? ? ? ? ? ? finally ? ? ? ? ? ? { ? ? ? ? ? ? ? ? if (stream != null) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? stream.Close(); stream.Dispose();
? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? if (req != null) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? req.Abort(); ? ? ? ? ? ? ? ? ? ? req = null; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? if (res != null) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? res.Close(); res = null;
? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? return result; ? ? ? ? }
发现图片处理时发生错误(另一个函数),一路从图片处理的另一个函数追踪到这里,发现图片抓取后,虽然程序认为正常抓取到了图片,但是图片信息不完整,大小会变少。
因为从别的网站抓取图片好用,只有这个django网站不好使,所以开始很自然以为是django网站静态资源配置的问题(这些坑做过django的小伙伴应该都很清楚了),这就是为什么我耽误了两天时间才找到问题的原因,找错方向了。先是在setting.py中一顿操作,发现django网站是可以通过浏览器正常显示图片的但是就是不能远程抓取。又以为是网站MIME的设置问题,结果也没有发现异常。于是怀疑还是c#中问题。
因为抓取到的图片比原图要小,突然看到req.Headers.Add("Accept-Encoding", "gzip, deflate");这行,gzip是我在django中做过设置的,只知道是可以将数据压缩进行传输,图片变小莫非和这个头部属性有关?将这行代码修改一下req.Headers.Add("Accept-Encoding", "");,竟然一下子就没问题了。
总结一下,应该是过去抓取其它网站时,那些网站没有提供gzip的压缩方法,所以可以直接抓取原图。但是抓取我的django网站时,由于网站提供了gzip的压缩方式,而我抓取时又模拟浏览器请求(默认的就是有gzip),但是却并没有对压缩响应的数据进行解压处理,导致图片文件错误。看来以后要模拟浏览器请求时还真得多加一分小心。
|