原文 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 = ;
httprequst.AllowAutoRedirect = true;//是否允许302
ServicePointManager.DefaultConnectionLimit = ;
//获取响应
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 = ;
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(".") + , (url.Length - url.LastIndexOf(".") - ));
FileStream writer = new FileStream(Global.FloderUrl + aFirstName + "." + aLastName, FileMode.OpenOrCreate, FileAccess.Write);
byte[] buff = new byte[];
//实际读取的字节数
int c = ;
while ((c = reader.Read(buff, , buff.Length)) > )
{
writer.Write(buff, , c);
}
writer.Close();
writer.Dispose();
reader.Close();
reader.Dispose();
response.Close();
return (aFirstName + "." + aLastName);
}
catch (Exception)
{
return "错误:地址" + url;
}
}
return "错误:地址为空";
}

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

C# 多线程网络爬虫的更多相关文章

  1. crawler4j:轻量级多线程网络爬虫实例

    crawler4j是Java实现的开源网络爬虫.提供了简单易用的接口,可以在几分钟内创建一个多线程网络爬虫. 下面实例结合jsoup(中文版API),javacvs 爬取自如租房网(http://sh ...

  2. crawler4j:轻量级多线程网络爬虫

    crawler4j是Java实现的开源网络爬虫.提供了简单易用的接口,可以在几分钟内创建一个多线程网络爬虫. 安装 使用Maven 使用最新版本的crawler4j,在pom.xml中添加如下片段: ...

  3. [原创]一款基于Reactor线程模型的java网络爬虫框架

    AJSprider 概述 AJSprider是笔者基于Reactor线程模式+Jsoup+HttpClient封装的一款轻量级java多线程网络爬虫框架,简单上手,小白也能玩爬虫, 使用本框架,只需要 ...

  4. 网络爬虫(java)

       陆陆续续做了有一个月,期间因为各种技术问题被多次暂停,最关键的一次主要是因为存储容器使用的普通二叉树,在节点权重相同的情况下导致树高增高,在进行遍历的时候效率大大降低,甚至在使用递归的时候导致栈 ...

  5. 开源的49款Java 网络爬虫软件

    参考地址 搜索引擎 Nutch Nutch 是一个开源Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫. Nutch的创始人是Doug Cutting, ...

  6. [搜片神器]之DHT网络爬虫的C++程序初步开源

    回应大家的要求,特地整理了一开始自己整合的代码,这样最简单,最直接的可以分析流程,至于文章里面提供的程序界面更多,需要大家自己开发. 谢谢园子朋友的支持,已经找到个VPS进行测试,国外的服务器: ht ...

  7. 网络爬虫系统Heritrix的结构分析 (个人读书报告)

      摘要 随着网络时代的日新月异,人们对搜索引擎,网页的内容,大数据处理等问题有了更多的要求.如何从海量的互联网信息中选取最符合要求的信息成为了新的热点.在这种情况下,网络爬虫框架heritrix出现 ...

  8. 一个简单的多线程Python爬虫(一)

    一个简单的多线程Python爬虫 最近想要抓取拉勾网的数据,最开始是使用Scrapy的,但是遇到了下面两个问题: 前端页面是用JS模板引擎生成的 接口主要是用POST提交参数的 目前不会处理使用JS模 ...

  9. 网络爬虫的C++程序

    [搜片神器]之DHT网络爬虫的C++程序初步开源 回应大家的要求,特地整理了一开始自己整合的代码,这样最简单,最直接的可以分析流程,至于文章里面提供的程序界面更多,需要大家自己开发. 谢谢园子朋友的支 ...

随机推荐

  1. cygwin如何断点续传

    对于Cygwin,如果想安装的东西比较多的话,推荐先选择“Download without installing”,下载完了再从本地安装. 好了,说关于断点续传.我所知道的是—— 网上有说法:下载失败 ...

  2. platform_driver_register(),platform_device_register()区别

    设备与驱动的两种绑定方式:在设备注册时进行绑定及在驱动注册时进行绑定. 以一个USB设备为例,有两种情形: (1)先插上USB设备并挂到总线中,然后在安装USB驱动程序过程中从总线上遍历各个设备,看驱 ...

  3. java io知识点汇总FIle类

    1.路径分隔符问题: 因为java有跨平台行,而在windows和linux中的目录分隔符是不同的.windows是"\" 而linux是"/"  所以必须想办 ...

  4. liunx下tomcat启动报错

    liunx下tomcat启动 Cannot find ./catalina.sh 2013-08-23 11:50 1521人阅读 评论(0) 收藏 举报 Cannot find ./catalina ...

  5. 在VS2012后的版本中做数据报表时,提示尚未指定报表“Report1”的报表定义

    有一群的朋友在用VS2012做数据报表时,老是提示 本地报表处理期间出错. 尚未指定报表“Report1”的报表定义 未将对象引用设置到对象的实例. 我看了一下,步骤没错,我用VS2010做了一下,一 ...

  6. 50. Pow(x, n)

    题目: Implement pow(x, n). 链接: http://leetcode.com/problems/powx-n/ 题解: 使用二分法求实数幂,假如不建立临时变量halfPow,直接r ...

  7. Android handler真的是重新启动一个线程吗?

    我们说handler是开启了另外一个线程,而且看代码的话确实是这样,实现了runnable接口,这在java中就是开启了一个线程,但是情况中的是这样吗?我们不妨来做个试验,如下 import andr ...

  8. C++异常以及异常与析构函数

    1. 抛出异常 1.1 抛出异常(也称为抛弃异常)即检测是否产生异常,在C++中,其采用throw语句来实现,如果检测到产生异常,则抛出异常. 该语句的格式为: throw 表达式; 如果在try语句 ...

  9. 深度神经网络入门教程Deep Neural Networks: A Getting Started Tutorial

    Deep Neural Networks are the more computationally powerful cousins to regular neural networks. Learn ...

  10. 用imagemagick和tesseract-ocr破解简单验证码

    用imagemagick和tesseract-ocr破解简单验证码 Tesseract-ocr据说辨识程度是世界排名第三,可谓神器啊. 准备工作: 1.安装tesseract-ocr sudo apt ...