上一篇《用C#实现网络爬虫(一)》我们实现了网络通信的部分,接下来继续讨论爬虫的实现

3. 保存页面文件

这一部分可简单可复杂,如果只要简单地把HTML代码全部保存下来的话,直接存文件就行了。

 1 private void SaveContents(string html, string url)
 2 {
 3     if (string.IsNullOrEmpty(html)) //判断html字符串是否有效
 4     {
 5         return;
 6     }
 7     string path = string.Format("{0}\\{1}.txt", _path, _index++); //生成文件名
 8
 9     try
10     {
11         using (StreamWriter fs = new StreamWriter(path))
12         {
13             fs.Write(html); //写文件
14         }
15     }
16     catch (IOException ioe)
17     {
18         MessageBox.Show("SaveContents IO" + ioe.Message + " path=" + path);
19     }
20
21     if (ContentsSaved != null)
22     {
23         _ui.Dispatcher.Invoke(ContentsSaved, path, url); //调用保存文件事件
24     }
25 }

第23行这里又出现了一个事件,是保存文件之后触发的,客户程序可以之前进行注册。

1 public delegate void ContentsSavedHandler(string path, string url);
2
3 /// <summary>
4 /// 文件被保存到本地后触发
5 /// </summary>
6 public event ContentsSavedHandler ContentsSaved = null;

4. 提取页面链接

提取链接用正则表达式就能搞定了,不懂的可以上网搜。

下面的字符串就能匹配到页面中的链接

http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?

详细见代码

 1 private string[] GetLinks(string html)
 2 {
 3     const string pattern = @"http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
 4     Regex r = new Regex(pattern, RegexOptions.IgnoreCase); //新建正则模式
 5     MatchCollection m = r.Matches(html); //获得匹配结果
 6     string[] links = new string[m.Count];
 7
 8     for (int i = 0; i < m.Count; i++)
 9     {
10         links[i] = m[i].ToString(); //提取出结果
11     }
12     return links;
13 }

5. 链接的过滤

不是所有的链接我们都需要下载,所以通过过滤,去掉我们不需要的链接

这些链接一般有:

  • 已经下载的链接
  • 深度过大的链接
  • 其他的不需要的资源,如图片、CSS等
 1 //判断链接是否已经下载或者已经处于未下载集合中
 2 private bool UrlExists(string url)
 3 {
 4     bool result = _urlsUnload.ContainsKey(url);
 5     result |= _urlsLoaded.ContainsKey(url);
 6     return result;
 7 }
 8
 9 private bool UrlAvailable(string url)
10 {
11     if (UrlExists(url))
12     {
13         return false; //已经存在
14     }
15     if (url.Contains(".jpg") || url.Contains(".gif")
16         || url.Contains(".png") || url.Contains(".css")
17         || url.Contains(".js"))
18     {
19         return false; //去掉一些图片之类的资源
20     }
21     return true;
22 }
23
24 private void AddUrls(string[] urls, int depth)
25 {
26     if (depth >= _maxDepth)
27     {
28         return; //深度过大
29     }
30     foreach (string url in urls)
31     {
32         string cleanUrl = url.Trim(); //去掉前后空格
33         cleanUrl = cleanUrl.TrimEnd('/'); //统一去掉最后面的'/'
34         if (UrlAvailable(cleanUrl))
35         {
36             if (cleanUrl.Contains(_baseUrl))
37             {
38                 _urlsUnload.Add(cleanUrl, depth); //是内链,直接加入未下载集合
39             }
40             else
41             {
42                 // 外链处理
43             }
44         }
45     }
46 }

第34行的_baseUrl是爬取的基地址,如http://news.sina.com.cn/,将会保存为news.sina.com.cn,当一个URL包含此字符串时,说明是该基地址下的链接;否则为外链。

_baseUrl的处理如下,_rootUrl是第一个要下载的URL

 1 /// <summary>
 2 /// 下载根Url
 3 /// </summary>
 4 public string RootUrl
 5 {
 6     get
 7     {
 8         return _rootUrl;
 9     }
10     set
11     {
12         if (!value.Contains("http://"))
13         {
14             _rootUrl = "http://" + value;
15         }
16         else
17         {
18             _rootUrl = value;
19         }
20         _baseUrl = _rootUrl.Replace("www.", ""); //全站的话去掉www
21         _baseUrl = _baseUrl.Replace("http://", ""); //去掉协议名
22         _baseUrl = _baseUrl.TrimEnd('/'); //去掉末尾的'/'
23     }
24 }

至此,基本的爬虫功能实现就介绍完了。

最后附上源代码和DEMO程序,爬虫的源代码在Spider.cs中,DEMO是一个WPF的程序,Test里是一个控制台的单线程版版本。

百度云网盘 链接:http://pan.baidu.com/s/1pKMfI8F 密码:3vzh

GJM :于 2016-11-16 转载自 http://www.cnblogs.com/Jiajun/archive/2012/06/17/2552458.html   如影响作者版权问题 请联系我 993056011@163.com

在下一期中,我们将介绍一些提取出网页中有效信息的方法,敬请期待。。。

GJM:用C#实现网络爬虫(二) [转载]的更多相关文章

  1. Python初学者之网络爬虫(二)

    声明:本文内容和涉及到的代码仅限于个人学习,任何人不得作为商业用途.转载请附上此文章地址 本篇文章Python初学者之网络爬虫的继续,最新代码已提交到https://github.com/octans ...

  2. Python网络爬虫(二)

    Urllib库之解析链接 Urllib库里有一个parse这个模块,定义了处理URL的标准接口,实现 URL 各部分的抽取,合并以及链接转换.它支持如下协议的 URL 处理:file.ftp.goph ...

  3. 【Python网络爬虫二】使用urllib2抓去网页内容

    在Python中通过导入urllib2组件,来完成网页的抓取工作.在python3.x中被改为urllib.request. 爬取具体的过程类似于使用程序模拟IE浏览器的功能,把URL作为HTTP请求 ...

  4. Python网络爬虫与如何爬取段子的项目实例

    一.网络爬虫 Python爬虫开发工程师,从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页 ...

  5. GJM:用C#实现网络爬虫(一) [转载]

    网络爬虫在信息检索与处理中有很大的作用,是收集网络信息的重要工具. 接下来就介绍一下爬虫的简单实现. 爬虫的工作流程如下 爬虫自指定的URL地址开始下载网络资源,直到该地址和所有子地址的指定资源都下载 ...

  6. 【网络爬虫】【java】微博爬虫(二):如何抓取HTML页面及HttpClient使用

    一.写在前面 上篇文章以网易微博爬虫为例,给出了一个很简单的微博爬虫的爬取过程,大概说明了网络爬虫其实也就这么回事,或许初次看到这个例子觉得有些复杂,不过没有关系,上篇文章给的例子只是让大家对爬虫过程 ...

  7. SHELL网络爬虫实例剖析--转载

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://nolinux.blog.51cto.com/4824967/1552472 前天 ...

  8. Golang 网络爬虫框架gocolly/colly 二 jQuery selector

    Golang 网络爬虫框架gocolly/colly 二 jQuery selector colly框架依赖goquery库,goquery将jQuery的语法和特性引入到了go语言中.如果要灵活自如 ...

  9. C语言Linix服务器网络爬虫项目(二)项目设计和通过一个http请求抓取网页的简单实现

    我们通过上一篇了解了爬虫具体要实现的工作之后,我们分析得出的网络爬虫的基本工作流程如下: 1.首先选取一部分精心挑选的种子URL: 2.将这些URL放入待抓取URL队列: 3.从待抓取URL队列中取出 ...

随机推荐

  1. uva11426 gcd、欧拉函数

    题意:给出N,求所有满足i<j<=N的gcd(i,j)之和 这题去年做过一次... 设f(n)=gcd(1,n)+gcd(2,n)+......+gcd(n-1,n),那么answer=S ...

  2. 轮询、select、 epoll

    网卡设备对应一个中断号, 当网卡收到网络端的消息的时候会向CPU发起中断请求, 然后CPU处理该请求. 通过驱动程序 进而操作系统得到通知, 系统然后通知epoll, epoll通知用户代码.  一. ...

  3. 第一个项目--用bootstrap实现美工设计的首页

    主要介绍在首页实现中用到bootstrap实现效果的地方. 实现如下的效果: <li> <div role="group" style="padding ...

  4. java.lang.IllegalStateException: You need to use a theme.appcompat theme (or descendant) with this activity

    错误描述:java.lang.IllegalStateException: You need to use a theme.appcompat theme (or descendant) with t ...

  5. cocos2d-x游戏开发系列教程-坦克大战游戏之子弹的碰撞检测处理

    在上篇我们加上了简单的坦克之间的碰撞检测,这篇我们继续加上子弹之间, 子弹与坦克之间的碰撞检测,对于上一篇碰撞处理不太完美的地方我们继续改进. 1.子弹之间的碰撞 //玩家子弹和敌方子弹之间的碰撞 C ...

  6. Linux时间转标准时间

    [root@nhserver2 ~]# date -d '1970-1-1 0:0:0 GMT + 1394592071 seconds'Wed Mar 12 10:41:11 CST 2014

  7. C# Net MVC 大文件下载几种方式、支持速度限制、资源占用小

    上一篇我们说到大文件的分片下载.断点续传.秒传,有的博友就想看分片下载,我们也来总结一下下载的几种方式,写的比较片面,大家见谅^_^. 下载方式: 1.html超链接下载: 2.后台下载(四种方法:返 ...

  8. bzoj 4244 括号序列dp

    将各种情况绕环等看作括号序列,括号内的区域上下都需要累加答案,左右也是 f[i][j] 代表 前i个车站已经处理完的有j个左括号的最小权值 我们可以发现,更新的来源来自于 i-1, 和 i 将上 描述 ...

  9. Zookeeper集群搭建步骤及相关知识点深入了解

    1.zookeeper概念 zookeeper是一个分布式协调服务:a:zookeeper是为别的分布式程序服务的 b:zookeeper本身就是一个分布式程序(只要半数以上节点存活,zookeepe ...

  10. js 获取浏览器/网页宽度高度整理

    网页宽度.高度: 网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight 网页可见区域宽: document.bo ...