C# 多线程网络爬虫

简介:

原文 C#制作多线程处理强化版网络爬虫

上次做了一个帮公司妹子做了爬虫,不是很精致,这次公司项目里要用到,于是有做了一番修改,功能添加了网址图片采集,下载,线程处理界面网址图片下载等。

说说思路:首相获取初始网址的所有内容 在初始网址采集图片 去初始网址采集链接 把采集到的链接放入队列 继续采集图片,然后继续采集链接,无限循环

还是上图片大家看一下:

处理网页内容抓取跟网页网址爬取都做了改进,下面还是大家来看看代码,有不足之处,还请之处!

网页内容抓取HtmlCodeRequest,

网页网址爬取GetHttpLinks,用正则去筛选html中的Links

图片抓取GetHtmlImageUrlList,用正则去筛选html中的Img

都写进了一个封装类里面 HttpHelper

复制代码
 /// <summary>  
    /// 取得HTML中所有图片的 URL。  
    /// </summary>  
    /// <param name="sHtmlText">HTML代码</param>  
    /// <returns>图片的URL列表</returns> 
public static string HtmlCodeRequest(string Url)
    {
      if (string.IsNullOrEmpty(Url))
      {
        return "";
      }
      try
      {
        //创建一个请求
        HttpWebRequest httprequst = (HttpWebRequest)WebRequest.Create(Url);
        //不建立持久性链接
        httprequst.KeepAlive = true;
        //设置请求的方法
        httprequst.Method = "GET";
        //设置标头值
        httprequst.UserAgent = "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705";
        httprequst.Accept = "*/*";
        httprequst.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5");
        httprequst.ServicePoint.Expect100Continue = false;
        httprequst.Timeout = 5000;
        httprequst.AllowAutoRedirect = true;//是否允许302
        ServicePointManager.DefaultConnectionLimit = 30;
        //获取响应
        HttpWebResponse webRes = (HttpWebResponse)httprequst.GetResponse();
        //获取响应的文本流
        string content = string.Empty;
        using (System.IO.Stream stream = webRes.GetResponseStream())
        {
          using (System.IO.StreamReader reader = new StreamReader(stream, System.Text.Encoding.GetEncoding("utf-8")))
          {
            content = reader.ReadToEnd();
          }
        }
        //取消请求
        httprequst.Abort();
        //返回数据内容
        return content;
      }
      catch (Exception)
      {
 
        return "";
      }
    }
/// <summary>
    /// 提取页面链接
    /// </summary>
    /// <param name="html"></param>
    /// <returns></returns>
public static List<string> GetHtmlImageUrlList(string url)
    {
      string html = HttpHelper.HtmlCodeRequest(url);
      if (string.IsNullOrEmpty(html))
      {
        return new List<string>();
      }
      // 定义正则表达式用来匹配 img 标签  
      Regex regImg = new Regex(@"<img\b[^<>]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?<imgUrl>[^\s\t\r\n""'<>]*)[^<>]*?/?[\s\t\r\n]*>", RegexOptions.IgnoreCase);
 
      // 搜索匹配的字符串  
      MatchCollection matches = regImg.Matches(html);
      List<string> sUrlList = new List<string>();
 
      // 取得匹配项列表  
      foreach (Match match in matches)
        sUrlList.Add(match.Groups["imgUrl"].Value);
      return sUrlList;
    }
 
 
    /// <summary>
    /// 提取页面链接
    /// </summary>
    /// <param name="html"></param>
    /// <returns></returns>
    public static List<string> GetHttpLinks(string url)
    {
      //获取网址内容
      string html = HttpHelper.HtmlCodeRequest(url);
      if (string.IsNullOrEmpty(html))
      {
        return new List<string>();
      }
      //匹配http链接
      const string pattern2 = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
      Regex r2 = new Regex(pattern2, RegexOptions.IgnoreCase);
      //获得匹配结果
      MatchCollection m2 = r2.Matches(html);
      List<string> links = new List<string>();
      foreach (Match url2 in m2)
      {
        if (StringHelper.CheckUrlIsLegal(url2.ToString()) || !StringHelper.IsPureUrl(url2.ToString()) || links.Contains(url2.ToString()))
          continue;
        links.Add(url2.ToString());
      }
      //匹配href里面的链接
      const string pattern = @"(?i)<a\s[^>]*?href=(['""]?)(?!javascript|__doPostBack)(?<url>[^'""\s*#<>]+)[^>]*>"; ;
      Regex r = new Regex(pattern, RegexOptions.IgnoreCase);
      //获得匹配结果
      MatchCollection m = r.Matches(html);
      foreach (Match url1 in m)
      {
        string href1 = url1.Groups["url"].Value;
        if (!href1.Contains("http"))
        {
          href1 = Global.WebUrl + href1;
        }
        if (!StringHelper.IsPureUrl(href1) || links.Contains(href1)) continue;
        links.Add(href1);
      }
      return links;
    }  
复制代码

这边下载图片有个任务条数限制,限制是200条。如果超过的话线程等待5秒,这里下载图片是异步调用的委托

复制代码
public string DownLoadimg(string url)
    {
      if (!string.IsNullOrEmpty(url))
      {
        try
        {
          if (!url.Contains("http"))
          {
            url = Global.WebUrl + url;
          }
          HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
          request.Timeout = 2000;
          request.UserAgent = "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705";
          //是否允许302
          request.AllowAutoRedirect = true;
          WebResponse response = request.GetResponse();
          Stream reader = response.GetResponseStream();
          //文件名
          string aFirstName = Guid.NewGuid().ToString();
          //扩展名
          string aLastName = url.Substring(url.LastIndexOf(".") + 1, (url.Length - url.LastIndexOf(".") - 1));
          FileStream writer = new FileStream(Global.FloderUrl + aFirstName + "." + aLastName, FileMode.OpenOrCreate, FileAccess.Write);
          byte[] buff = new byte[512];
          //实际读取的字节数
          int c = 0;
          while ((c = reader.Read(buff, 0, buff.Length)) > 0)
          {
            writer.Write(buff, 0, c);
          }
          writer.Close();
          writer.Dispose();
          reader.Close();
          reader.Dispose();
          response.Close();
          return (aFirstName + "." + aLastName);
        }
        catch (Exception)
        {
          return "错误:地址" + url;
        }
      }
      return "错误:地址为空";
    }
复制代码

话不多说,更多的需要大家自己去改进咯!

 

没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。



    本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/5885082.html ,如需转载请自行联系原作者



相关文章
|
数据采集 移动开发 C#
|
数据采集 数据格式 JSON
记爬虫小分队(二)
2017年4月19日,关于简书收录专题爬取的思路。 1.首先是异步加载,这里就不多说,就是找包,下图为收录专题的加载的包。 2.可在Preview中看到json数据的格式,我们可以看到一个total_page,这个为收录专题的总页数(非常重要!!!!)。
907 0
|
Web App开发 数据采集 Windows
记爬虫小分队(六)
2017年5月18日 今天有同学问我贴吧为什么信息提取不出来? 下面是同学的源代码: import requests from bs4 import BeautifulSoup start_url = "http://tieba.
825 0
|
Web App开发 数据采集 JavaScript
爬虫问题总结
本文档对日常学习中用 python 做数据爬取时所遇到的一些问题做简要记录,以便日后查阅,部分问题可能因为认识不到位会存在一些误解,敬请告知,万分感谢,共同进步。 估算网站规模 该小节主要针对于整站爬取的情况。
1864 0
|
10月前
|
数据采集 Web App开发 安全
爬虫
该文介绍了爬虫的基础知识,包括爬虫的定义(通过编程模拟浏览器抓取网络数据)、价值(实际应用和就业需求)、法律地位(合法但有违法风险,分为善意和恶意爬虫)以及可能带来的风险(影响网站运营和触犯法律)。为避免问题,建议优化程序、审查抓取内容。爬虫类型包括通用、聚焦和增量式爬虫。文中还提到了反爬与反反爬策略,以及robots.txt协议作为网站数据爬取的君子协定。此外,讨论了HTTP协议(包括User-Agent和Connection)和HTTPS协议的安全性及加密方式。
140 0
|
Web App开发 数据采集 Python
当我们写爬虫的时候,我们实际在做什么?
当我开始学习爬虫的时候,我在网上也开始找相关教程,大多数都是xx分钟学会爬虫一类的文章。并不是否定这些文章的价值,因为他们的确“教会”我如何爬取网页。但我不想停留只会使用工具这一层面上,这就是我想谈谈自己对爬虫的理解。
1307 0
|
10月前
|
数据采集 搜索推荐 数据挖掘
爬虫应用
爬虫应用
77 2
|
存储 数据采集
记爬虫小分队(五)
有点标题党 2017年4月29日 程兄说,五一的标配是和女神游山玩水,你这样说了,那我就免为其难的秀一波,希望你不要打我。 2017年4月30日 第一次在熊猫开直播讲爬虫入门,以前有人在网吧看新闻联播,画CAD,学习,今天也是做了一次网吧的清流。
1032 0
|
数据采集 Java 索引
gecco爬虫
http://www.geccocrawler.com/intro/ Gecco是一款用java语言开发的轻量化的易用的网络爬虫,不同于Nutch这样的面向搜索引擎的通用爬虫,Gecco是面向主题的爬虫。
999 0
|
数据采集 存储 JSON
一文学会爬虫技巧
作为冷数据启动和丰富数据的重要工具,爬虫在业务发展中承担着重要的作用,我们业务在发展过程中积累了不少爬虫使用的经验,在此分享给大家,希望能对之后的业务发展提供一些技术选型方向上的思路,以更好地促进业务发展
一文学会爬虫技巧

热门文章

最新文章