HttpWebRequest抓取图片

chengwangtianxia 2013-04-28 10:59:22
public static bool downloadFile(string url, string savePath, ref Exception ex,ref int fileSize)
{
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;
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 (Exception exception)
{
ex = exception;
}
finally
{
if (stream != null)
{
stream.Close(); stream.Dispose();
}
if (req != null)
{
req.Abort();
req = null;
}
if (res != null)
{
res.Close();
res = null;
}
}
return result;
}

我自己搞了个小爬虫软件玩玩,抓取网站的图片,主要代码如上。
一开始抓取的时候是没问题的,但是抓取到一定数量的时候(1000到3000张图片之间),抓取速度越来越慢,抓取花费的时候,一直不断攀升,最后甚至长达几分钟,而且多数是超时失败了。
我把那些失败的图片地址拷贝到浏览器直接访问,大部分是没问题。请教各位大虾,有什么优化方案吗?哦,对了,我是用多线程的,不论我开多少线程(一般在20个左右)在抓取,到了一定时候,都会出现这情况。
...全文
274 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
chengwangtianxia 2013-04-28
  • 打赏
  • 举报
回复
不是,现在的问题是 using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 这一句代码,等待响应的时间太长了,其它的都不会有所阻塞。我在想是不是之前的网络连接没有释放掉,导致后面的连接一直在等待?
md5e 2013-04-28
  • 打赏
  • 举报
回复
引用 8 楼 chengwangtianxia 的回复:
res.Close(); res = null; 这两句代码,效果应该跟using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())一样的吧。 刚刚我把代码改成using,还是一样。
那就看看你的线程这块代码咧
我是小李 2013-04-28
  • 打赏
  • 举报
回复
引用 9 楼 chengwangtianxia 的回复:
[quote=引用 7 楼 ly_sl 的回复:] while (bytesRead > 0);这句干什么的
循环读取流,直到尽头。[/quote] 呵呵,没看到上面的do语句 为什么不直接用WebClient的WebClient方法
chengwangtianxia 2013-04-28
  • 打赏
  • 举报
回复
引用 7 楼 ly_sl 的回复:
while (bytesRead > 0);这句干什么的
循环读取流,直到尽头。
chengwangtianxia 2013-04-28
  • 打赏
  • 举报
回复
res.Close(); res = null; 这两句代码,效果应该跟using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())一样的吧。 刚刚我把代码改成using,还是一样。
我是小李 2013-04-28
  • 打赏
  • 举报
回复
while (bytesRead > 0);这句干什么的
md5e 2013-04-28
  • 打赏
  • 举报
回复
引用 5 楼 chengwangtianxia 的回复:
[quote=引用 4 楼 liuchaolin 的回复:] [quote=引用 2 楼 chengwangtianxia 的回复:] [quote=引用 1 楼 liuchaolin 的回复:] images直接有.save
问题不在这里哦,我调试的时候,发现时间都耗费在等待响应上了,保存并不占用多少时间。[/quote] 那是因为你没有即时释放资源[/quote] finally { if (stream != null) { stream.Close(); stream.Dispose(); } if (req != null) { req.Abort(); req = null; } if (res != null) { res.Close(); res = null; } } 这段代码,不是在释放资源吗?关闭流,关闭request连接,还有什么资源没关闭吗?[/quote] using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
chengwangtianxia 2013-04-28
  • 打赏
  • 举报
回复
引用 4 楼 liuchaolin 的回复:
[quote=引用 2 楼 chengwangtianxia 的回复:] [quote=引用 1 楼 liuchaolin 的回复:] images直接有.save
问题不在这里哦,我调试的时候,发现时间都耗费在等待响应上了,保存并不占用多少时间。[/quote] 那是因为你没有即时释放资源[/quote] finally { if (stream != null) { stream.Close(); stream.Dispose(); } if (req != null) { req.Abort(); req = null; } if (res != null) { res.Close(); res = null; } } 这段代码,不是在释放资源吗?关闭流,关闭request连接,还有什么资源没关闭吗?
md5e 2013-04-28
  • 打赏
  • 举报
回复
引用 2 楼 chengwangtianxia 的回复:
[quote=引用 1 楼 liuchaolin 的回复:] images直接有.save
问题不在这里哦,我调试的时候,发现时间都耗费在等待响应上了,保存并不占用多少时间。[/quote] 那是因为你没有即时释放资源
md5e 2013-04-28
  • 打赏
  • 举报
回复
request = WebRequest.Create(picpath) as HttpWebRequest;//picpath,图片地址 request.Method = "GET"; request.Timeout = 30000; request.AllowAutoRedirect = true; request.ContentType = "image/bmp"; request.UserAgent = "Mozilla/5.0 (Windows NT 5.2; rv:11.0) Gecko/20100101 Firefox/11.0"; request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")); Bitmap sourcebm = new Bitmap(sr.BaseStream); sr.Close(); sourcebm.Save(filename);//filename 保存地址 }
chengwangtianxia 2013-04-28
  • 打赏
  • 举报
回复
引用 1 楼 liuchaolin 的回复:
images直接有.save
问题不在这里哦,我调试的时候,发现时间都耗费在等待响应上了,保存并不占用多少时间。
md5e 2013-04-28
  • 打赏
  • 举报
回复
images直接有.save
chengwangtianxia 2013-04-28
  • 打赏
  • 举报
回复
呵呵,13楼的兄弟,我要的,不是网页截图。
  • 打赏
  • 举报
回复

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Runtime.InteropServices.ComTypes;

namespace WebMonitor
{
    /// <summary>
    /// ActiveX 组件网页快照类
    /// </summary>
    public class WebSnapshot
    {
        /// <summary>
        /// 实现网页快照
        /// </summary>
        /// <param name="pUnknown">Active组件</param>
        /// <param name="bmpRect">Rectangle对象</param>
        /// <returns></returns>
        public Bitmap TakeSnapshot(object pUnknown, Rectangle bmpRect)
        {
            if (pUnknown == null)
                return null;
            //必须为com对象
            if (!Marshal.IsComObject(pUnknown))
                return null;
            //IViewObject 接口
            UnsafeNativeMethods.IViewObject ViewObject = null;
            IntPtr pViewObject = IntPtr.Zero;

            //新建一个bmp图片 
            Bitmap pPicture = new Bitmap(bmpRect.Width, bmpRect.Height);

            //新建一个画板 
            Graphics hDrawDC = Graphics.FromImage(pPicture);
            //获取接口
            object hret = Marshal.QueryInterface(Marshal.GetIUnknownForObject(pUnknown),
                ref UnsafeNativeMethods.IID_IViewObject, out pViewObject);
            try
            {
                ViewObject = Marshal.GetTypedObjectForIUnknown(pViewObject, typeof(UnsafeNativeMethods.IViewObject)) as UnsafeNativeMethods.IViewObject;
                //调用Draw方法
                ViewObject.Draw((int)DVASPECT.DVASPECT_CONTENT,
                    -1,
                    IntPtr.Zero,
                    null,
                    IntPtr.Zero,
                    hDrawDC.GetHdc(),
                    new NativeMethods.COMRECT(bmpRect),
                    null,
                    IntPtr.Zero,
                    0);
                Marshal.Release(pViewObject);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw ex;
            }
            hDrawDC.Dispose();
            return pPicture;
        }
    }
}



  /// <summary>
        /// 保存网页快照
        /// </summary>
        /// <param name="url"></param>
        /// <param name="path"></param>
        /// <param name="Width"></param>
        /// <param name="Height"></param>
        /// <returns></returns>
        public void SaveSnapshot(string url, string path, int Width, int Height)
        {
            //初始化窗体
            InitComobject(url);
            int scrollWidth = this.browser.Document.Body.ScrollRectangle.Width;
            int scrollHeight = this.browser.Document.Body.ScrollRectangle.Height;

            this.browser.Width = scrollWidth;
            this.browser.Height = scrollHeight;
            if (Width == 0)
            {
                Width = scrollWidth;
            }
            if (Height == 0)
            {
                Height = scrollHeight;
            }
            //截取网页快照封装到位图
            WebSnapshot snapshot = new WebSnapshot();
            using (Bitmap bitmap = snapshot.TakeSnapshot(this.browser.ActiveXInstance, new Rectangle(0, 0, Width, Height)))
            {
                bitmap.Save(path, ImageFormat.Jpeg);  //这有个GDI+ 中发生一般性错误异常,偶发性的,资源没有释放的问题,文件访问的问题,或者其他问题
            }
            browser.Dispose();
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="url"></param>
        protected void InitComobject(string url)
        {
            //this.browser.ScriptErrorsSuppressed = false;
            this.browser.ScrollBarsEnabled = false;
            this.browser.Navigate(url);
            //SuppressScriptErrorsOnly(this.browser);
            //保证页面完全加载
            while (this.browser.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }
            //挂起一切动态元素
            this.browser.Stop();

            if (this.browser.ActiveXInstance == null)
            {
                throw new Exception("实例不能为空");
            }
        }



62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧