之前用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),但是却并没有对压缩响应的数据进行解压处理,导致图片文件错误。看来以后要模拟浏览器请求时还真得多加一分小心。