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

3. 保存页面文件

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

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

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

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

4. 提取页面链接

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

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

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

详细见代码

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

5. 链接的过滤

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

这些链接一般有:

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

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

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

  1. 1 /// <summary>
  2. 2 /// 下载根Url
  3. 3 /// </summary>
  4. 4 public string RootUrl
  5. 5 {
  6. 6 get
  7. 7 {
  8. 8 return _rootUrl;
  9. 9 }
  10. 10 set
  11. 11 {
  12. 12 if (!value.Contains("http://"))
  13. 13 {
  14. 14 _rootUrl = "http://" + value;
  15. 15 }
  16. 16 else
  17. 17 {
  18. 18 _rootUrl = value;
  19. 19 }
  20. 20 _baseUrl = _rootUrl.Replace("www.", ""); //全站的话去掉www
  21. 21 _baseUrl = _baseUrl.Replace("http://", ""); //去掉协议名
  22. 22 _baseUrl = _baseUrl.TrimEnd('/'); //去掉末尾的'/'
  23. 23 }
  24. 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. NodeJs 入门到放弃 — 常用模块及网络爬虫(二)

    码文不易啊,转载请带上本文链接呀,感谢感谢 https://www.cnblogs.com/echoyya/p/14473101.html 目录 码文不易啊,转载请带上本文链接呀,感谢感谢 https ...

  3. Python网络爬虫(二)

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 每天一个linux命令(11):nl命令

    nl命令在linux系统中用来计算文件中行号.nl 可以将输出的文件内容自动的加上行号!其默认的结果与 cat -n 有点不太一样, nl 可以将行号做比较多的显示设计,包括位数与是否自动补齐 0 等 ...

  2. OpenCascade Shape Representation in OpenSceneGraph

    OpenCascade Shape Representation in OpenSceneGraph eryar@163.com 摘要Abstract:本文通过程序实例,将OpenCascade中的拓 ...

  3. 了解canvas

    目录 [1]HTML属性[2]CSS样式 [3]API 坐标 填充和描边 阴影 绘制矩形 绘制路径 绘制文本 绘制图像 使用图像 变换 合成 [4]DEMO 前面的话 canvas元素是HTML5最受 ...

  4. 深入理解CSS定位中的偏移

    × 目录 [1]定位 [2]包含块 [3]偏移属性[4]绝对定位[5]格式化 [6]auto 前面的话 CSS有三种基本的定位机制:普通流.浮动和绝对定位.利用定位,可以准确地定义元素框相对于其正常位 ...

  5. 2014 -> 2015

    2014年初在公司的发展不太顺利, 发现比好多小伙伴的发展速度都要慢了,钱不多,职位也不高,做的事情成长也不快. 为了职业发展考虑,年中就一直想换一个好一点的工作机会, 年中拿了好几个offer, 有 ...

  6. 在Abp中执行sql语句

    目录 前言 最近使用ABP(ASP.NET Boilerplate)做项目,有些查询(或存储过程)直接使用sql语句会更方便一点. 定义一个接口 在Core项目中定义一个接口,如:ISqlExecut ...

  7. js每天进步一点点4

    输入数字的验证

  8. Windows Azure Cloud Service (12) PaaS之Web Role, Worker Role, Azure Storage Queue(下)

    <Windows Azure Platform 系列文章目录> 本章DEMO部分源代码,请在这里下载. 在上一章中,笔者介绍了我们可以使用Azure PaaS的Web Role和Worke ...

  9. 基于HT for Web矢量实现3D叶轮旋转

    在上一篇<基于HT for Web矢量实现2D叶轮旋转>中讲述了叶轮旋转在2D上的应用,今天我们就来讲讲叶轮旋转在3D上的应用. 在3D拓扑上可以创建各种各样的图元,在HT for Web ...

  10. Chrome开发者工具详解(1)-Elements、Console、Sources面板

    Chrome开发者工具详解(1)-Elements.Console.Sources面板 Chrome开发者工具面板 面板上包含了Elements面板.Console面板.Sources面板.Netwo ...