热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

网络采集软件核心技术剖析系列(2)---如何使用C#语言获得任意站点博文的正文及标题

一本系列随笔概览及产生的背景本系列开篇受到大家的热烈欢迎,这对博主是莫大的鼓励,此为本系列第二篇,希望大家继续支持,为我继续写作提供动力。自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大

一 本系列随笔概览及产生的背景

本系列开篇受到大家的热烈欢迎,这对博主是莫大的鼓励,此为本系列第二篇,希望大家继续支持,为我继续写作提供动力。

自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写作和阅读爱好者的喜爱。同时也不乏一些技术爱好者咨询我,这个软件里面各种实用的功能是如何实现的。

该软件使用.NET技术开发,为回馈社区,现将该软件中用到的核心技术,开辟一个专栏,写一个系列文章,以飨广大技术爱好者。

本系列文章除了讲解网络采编发用到的各种重要技术之外,也提供了不少问题的解决思路和界面开发的编程经验,非常适合.NET开发的初级,中级读者,希望大家多多支持。

很多初学者常有此类困惑,“为什么我书也看了,C#相关的各个方面的知识都有所了解,但就是没法写出一个像样的应用呢?”,

这其实还是没有学会综合运用所学知识,锻炼出编程思维,建立起学习兴趣,我想该系列文章也许会帮到您,但愿如此。

开发环境:VS2008

本节源码位置:https://github.com/songboriceboy/GetWebContent

源码下载办法:安装SVN客户端(本文最后提供下载地址),然后checkout以下的地址:https://github.com/songboriceboy/GetWebContent

系列文章提纲拟定如下:

1.如何使用C#语言获取博客园某个博主的全部随笔链接及标题;
2.如何使用C#语言获得博文的正文及标题;
3.使用C#语言如何将html网页转换成pdf(html2pdf)
4.如何使用C#语言下载博文中的全部图片到本地并可以离线浏览
5.如何使用C#语言合成多个单个的pdf文件到一个pdf中,并生成目录
6.网易博客的链接如何使用C#语言获取到,网易博客的特殊性;
7.微信公众号文章如何使用C#语言下载;
8.如何获取任意一篇文章的全部图文
9.如何使用C#语言去掉html中的全部标签获取纯文本(html2txt)
10.如何使用C#语言将多个html文件编译成chm(html2chm)
11.如何使用C#语言远程发布文章到新浪博客
12.如何使用C#语言开发静态站点生成器
13.如何使用C#语言搭建程序框架(经典Winform界面,顶部菜单栏,工具栏,左边树形列表,右边多Tab界面)
14.如何使用C#语言实现网页编辑器(Winform)
......

二 第二节主要内容简介(如何使用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 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
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,静态站点,远程发布到其他站点等等(请继续关注本系列文章,并不吝点一下推荐,您的支持是我写作的最大动力)。


推荐阅读
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • ItriedtouseFirebugLite(viathebookmarkletandalsoaddingittooneofmywebsites).我尝试使用Fi ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 本文介绍了在使用Python中的aiohttp模块模拟服务器时出现的连接失败问题,并提供了相应的解决方法。文章中详细说明了出错的代码以及相关的软件版本和环境信息,同时也提到了相关的警告信息和函数的替代方案。通过阅读本文,读者可以了解到如何解决Python连接服务器失败的问题,并对aiohttp模块有更深入的了解。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • from:http:www.myquickphp.comarchives147(请求的跨域服务器不支持常规”?”查询请求时的解决方案)昨天第一次做VIP需求时,发现一 ... [详细]
  • 前端图片合成技术_靠谱的前端需要做哪些准备?
    Web前端开发源于传统的互联网,互联网普及让人才需求量居高不下,随着移动互联网的高速发展,移动终端的前端开发也越来越受到重视, ... [详细]
  • 有个事情移植想不明白
    后端开发|php教程不明白,移植,事情后端开发-php教程为什么我客户端通过http请求服务端服务端发张图片到客户端这个传输为什么那么慢一共也就300多kb但一共传了5秒多如果直接 ... [详细]
author-avatar
广东暖暖_小乖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有