一 本系列随笔概览及产生的背景css
本身开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写做和阅读爱好者的喜好。同时也不乏一些技术爱好者咨询我,这个软件里面各类实用的功能是如何实现的。html
该软件使用.NET技术开发,为回馈社区,现将该软件中用到的核心技术,开辟一个专栏,写一个系列文章,以飨广大技术爱好者。git
本系列文章除了讲解网络采编发用到的各类重要技术以外,也提供了很多问题的解决思路和界面开发的编程经验,很是适合.NET开发的初级,中级读者,但愿你们多多支持。github
不少初学者常有此类困惑,“为何我书也看了,C#相关的各个方面的知识都有所了解,但就是无法写出一个像样的应用呢?”,数据库
这其实仍是没有学会综合运用所学知识,锻炼出编程思惟,创建起学习兴趣,我想该系列文章也许会帮到您,希望如此。编程
开发环境:VS2008网页爬虫
本节源码位置:https://github.com/songboriceboy/GatherAll网络
源码下载办法:安装SVN客户端(本文最后提供下载地址),而后checkout如下的地址:https://github.com/songboriceboy/GatherAll数据结构
系列文章提纲以下:多线程
二 第五节主要内容简介(将任意博主的所有博文下载到内存中并经过Webbrower显示)
将任意博主的所有博文下载到内存中并经过Webbrower显示的解决方案,演示demo以下图所示:可执行文件下载
三 基本原理
本节咱们提供了一个示例将本系列中的第一节和第二节的内容综合到一块儿,实现下载博客园任意博主的所有博文功能。用户只要在编辑框中输入博客园任意博主的ID,该博主的所有文章就会被下载到内存中,咱们本节就来剖析一下实现原理。
采集博文的结构图以下所示:
整体步骤以下:
1.用分页地址初始化Url队列(实际上是一个堆栈数据结构),具体请参考本系列第一节内容;
2.调度器不断从Url队列中取得url,从网上获取该url对应的网页正文;
3.多线程的网页爬虫分析下载到的网页正文是连接提取页仍是文章正文页;
(1)若为连接提取页面,则提取所有符合规则的文章连接,而后压入到前面的Url队列中(实际上是堆栈操做,这里能够理解为,一个分页页面地址换取了几十个文章连接地址,接下来调度器将取得的连接是这几十个文章连接地址,所有下载完,存储到数据存储后,接下来才会轮到取第二个分页页面,这点你们能够对照提供的代码自行理解,此处是网络爬虫的精髓)。
(2)若为文章正文页,则按照正文css路径,提取出正文,存储到数据存储中(本节为datatable中),具体可参考本系列第二节内容。
4.递归的执行第2步和第3步,直至Url队列为空或已经判断出所有文章下载完毕(参见第一节)时,程序结束。
核心代码以下:
private void ParseWebPage(string strVisitUrl, string strPageContent, DoWorkEventArgs e) { string strUrlFilterRule = GetUrlFilterRule(); if (!IsFinalPage(strVisitUrl, strUrlFilterRule)) { bool bNoArticle = SaveUrlToDB(strVisitUrl, strPageContent, e); if (!bNoArticle) { BlogGatherNext(e); } } else { if (strPageContent != "") { string strTitle = SaveFinalPageContent("" , GetMainContentCss(), strVisitUrl, strPageContent); } BlogGatherNext(e); } }
IsFinalPage(strVisitUrl, strUrlFilterRule),该行代码根据本次请求的url和文章连接的url规则来判断当前获取的页面是最终文章页仍是文章连接提取页,其实现代码以下:
protected bool IsFinalPage(string strVisitUrl, string strUrlFilterRule) { bool bRet = false; MatchCollection matchsTemp = Regex.Matches(strVisitUrl.ToString(), strUrlFilterRule, RegexOptions.Singleline); if (matchsTemp.Count > 0) { bRet = true; } return bRet; }
补充说明,何谓连接提取页?以下图所示便是:
更详细的代码请自行下载研究。