一 本系列随笔概览及产生的背景css
本系列开篇受到你们的热烈欢迎,这对博主是莫大的鼓励,此为本系列第二篇,但愿你们继续支持,为我继续写做提供动力。html
本身开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写做和阅读爱好者的喜好。同时也不乏一些技术爱好者咨询我,这个软件里面各类实用的功能是如何实现的。node
该软件使用.NET技术开发,为回馈社区,现将该软件中用到的核心技术,开辟一个专栏,写一个系列文章,以飨广大技术爱好者。git
本系列文章除了讲解网络采编发用到的各类重要技术以外,也提供了很多问题的解决思路和界面开发的编程经验,很是适合.NET开发的初级,中级读者,但愿你们多多支持。github
不少初学者常有此类困惑,“为何我书也看了,C#相关的各个方面的知识都有所了解,但就是无法写出一个像样的应用呢?”,web
这其实仍是没有学会综合运用所学知识,锻炼出编程思惟,创建起学习兴趣,我想该系列文章也许会帮到您,希望如此。chrome
开发环境:VS2008数据库
本节源码位置:https://github.com/songboriceboy/GetWebContent编程
源码下载办法:安装SVN客户端(本文最后提供下载地址),而后checkout如下的地址:https://github.com/songboriceboy/GetWebContent浏览器
系列文章提纲以下:
二 第二节主要内容简介(如何使用C#语言得到任意站点博文的正文及标题)
使用C#语言得到任意站点博文的正文及标题的解决方案演示demo以下图所示:可执行文件下载
三 基本原理
要想获取任意网页文章的正文及标题,咱们除了要利用上一节提到的HtmlAgilityPack.dll程序集以外,还要借助于另一个实用的程序集Fizzler.dll(http://fizzlerex.codeplex.com/)
HtmlAgilityPack是经过xpath来解析html元素,相对来讲仍是稍微麻烦些;Fizzler提供了相似css选择器的方式来解析html元素,很是符合咱们的习惯。
一般对于某篇文章,咱们只想保留文章的正文(去掉广告,侧边栏等四周的网页布局元素),接下来,咱们就来看一下操做步骤,这里咱们须要借助一下强大的浏览器工具。
1.使用firefox浏览器或chrome浏览器打开咱们想要提取正文的网页,firefox要安装firebug插件,chrome直接按F12,这里咱们以firefox举例:
好比,打开咱们上一节的博文(http://www.cnblogs.com/ice-river/p/4110799.html),以下图所示:
首先右上角的小虫子图标在咱们安装完firebug插件后出现,点击它,浏览器下端弹出调试界面,在调试界面中,点击我红线框起来的图标(一蓝色方框,上面有个箭头),此时你会发现网页中的各个元素都变为可框选的,咱们框选正文以后,会发如今下面的调试界面对应的div元素被高亮选中,咱们对该div元素(博客园这里是div#cnblogs_post_body)右键,弹出右键菜单,以下图所示:
咱们点击[复制css路径菜单项],此时咱们粘贴板中就获得了正文的css路径[html body div#home div#main div#mainContent div.forFlow div#topics div.post div.postBody div#cnblogs_post_body]
对于Fizzler来讲,咱们只须要提供最后部分的div#cnblogs_post_body便可(你们记住,咱们只须要从得到的css路径长字符串中从后往前看,拿到最后一个空格以后的字符串,这里是div#cnblogs_post_body
把这个字符串填入到咱们demo的[正文css路径]部分,以下图所示:
其实对应于Fizzler来说,只需一行代码:
IEnumerable<HtmlNode> NodesMainContent = htmlDoc.DocumentNode.QuerySelectorAll(this.textBoxCssPath.Text);
是否是很简单?
对于其余技术博客,你们能够自行练习,检验是否理解了我上面所说的方法,这里给出几个常见技术博客的正文Css路径答案:
站点 ---> CSS路径 "Cnblogs" ---> "div#cnblogs_post_body" "Csdn" ---> "div#article_content.article_content" "51CTO" ---> "div.showContent" "Iteye" ---> "div#blog_content.blog_content" "ItPub" ---> "div.Blog_wz1" "ChinaUnix" ---> "div.Blog_wz1"
好了,回过头来咱们讲讲本节demo中的重点代码:
获取博客正文标题:
private void GetTitle() { string strContent = m_wd.GetPageByHttpWebRequest(this.textBoxUrl.Text, Encoding.UTF8); HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument { OptionAddDebuggingAttributes = false, OptionAutoCloseOnEnd = true, OptionFixNestedTags = true, OptionReadEncoding = true }; htmlDoc.LoadHtml(strContent); string strTitle = ""; HtmlNodeCollection nodes = htmlDoc.DocumentNode.SelectNodes("//title"); // Extract Title if (!Equals(nodes, null)) { strTitle = string.Join(";", nodes. Select(n => n.InnerText). ToArray()).Trim(); } strTitle = strTitle.Replace("博客园", ""); strTitle = Regex.Replace(strTitle, @"[|/\;:*?<>&#-]", "").ToString(); strTitle = Regex.Replace(strTitle, "[\"]", "").ToString(); this.textBoxTitle.Text = strTitle.TrimEnd(); }
主要流程是首先用咱们上一节给出的 WebDownloader类获取到网页的源代码,而后经过下面一行代码获取网页标题:
HtmlNodeCollection nodes = htmlDoc.DocumentNode.SelectNodes("//title");
这里的借助了HtmlAgilityPack的SelectNodes函数提取网页中的title元素,注意通常的格式良好网页都具备title元素,由于这样方便搜索引擎索引收录咱们的文章,下图解释下什么是title元素
你们注意上图,我用红笔圈出的2个地方,应该不言自明了吧,不解释。
获取博客正文内容:
private void GetMainContent() { string strContent = m_wd.GetPageByHttpWebRequest(this.textBoxUrl.Text, Encoding.UTF8); HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument { OptionAddDebuggingAttributes = false, OptionAutoCloseOnEnd = true, OptionFixNestedTags = true, OptionReadEncoding = true }; htmlDoc.LoadHtml(strContent); IEnumerable<HtmlNode> NodesMainContent = htmlDoc.DocumentNode.QuerySelectorAll(this.textBoxCssPath.Text); if (NodesMainContent.Count() > 0) { this.richTextBox1.Text = NodesMainContent.ToArray()[0].OuterHtml; this.webBrowser1.DocumentText = this.richTextBox1.Text; } }
很简单就是调用htmlDoc.DocumentNode.QuerySelectorAll函数,参数传入咱们上面讲到的正文div的css路径,最后NodesMainContent.ToArray()[0].OuterHtml中保存的就是网页正文内容的源代码,放到richTextBox1.Text里显示html源代码,放到webBrowser1.DocumentText里显示网页内容。
四 下节预告
网页的抓取主要分为3步:
1.经过分页连接抓取到所有文章连接集合(第一节内容)
2.经过每个文章连接获取到文章的标题及正文(本节内容)
3.从文章正文中解析出所有图片连接,并将文章的所有图片下载到本地(下节内容)
这3步有了,以后你就想怎么折腾就怎么折腾了,各类加工处理,生成pdf,chm,静态站点,远程发布到其余站点等等(请继续关注本系列文章,并不吝点一下推荐,您的支持是我写做的最大动力)。