网络爬虫

标签: Network 爬虫 网络 | 发表时间:2013-05-26 22:19 | 作者:四火
出处:http://www.raychase.net

文章系本人原创,转载请保持完整性并注明出自 《四火的唠叨》

最近在写一个程序,去爬热门事件和热门关键词网站上的数据。在这里介绍一下网络爬虫的种种。

基本组件

网络爬虫

网络爬虫也叫做网络蜘蛛,是一种互联网机器人,把需要的网页撷取下来,组织成适当格式存储。它是搜索引擎的重要组成部分,虽然从技术实现上来说,它的难度往往要小于对于得到的网页信息的处理。

上面这张图来自 维基百科,scheduler调度多个多线程的下载器下载网页,并把信息和元数据存储起来。而通过解析下载网页的数据,找到链接,又把链接加入到工作队列中去准备下载。这看起来是一个迭代的过程。

网络爬虫相关的几项重要策略:

  • 选择策略:哪些网页是需要被抓取的;
  • 重访问策略:怎样的方式去检测网页是否被修改过;
  • 礼貌性策略:抓取网页的时候,需要方式网站过载;
  • 并行化策略:怎样组织分布式的网络爬虫。

选择策略

限定跟随链接。通常只需要html文本信息,所以根据MIME类型,如果不是文本信息,会被丢弃掉。所以,如果URL无法得知资源的二进制类型,爬虫可能会先发起一个head请求获知目标是不是文本,如果是的话,才发送一个get请求获取页面。

URL标准化。它用来避免多次爬到相同的页面。有些URL包含“../”这样的相对路径信息,这也需要爬虫处理使之成为完整正确的URL,而有些URL则需要在最后面加上斜杠。

路径升序。有些爬虫想尽可能爬多的信息,资源是有层级关系的,比如 http://llama.org/hamster/monkey/page.html这样一个链接,它会尝试爬“/hamster/monkey/”、“/hamster/”和“/”这几个页面。

学术网页爬虫。专注于学术领域,比如Google Scholar等等。

重访问策略

网页总是在动态变化的,爬完整一个网站可能会花掉数周甚至一个月的时间,在爬完一个网页之后,网页可能就不在了,或者更新了。什么时候再爬这个网站呢?通常对于经常变化的网页,这个间隔时间应该短一些。

新鲜度:在一定时间t内,页面是否有变化

网络爬虫

Age: 本地网页拷贝有多么过时。

网络爬虫

有一种常见的重访问策略是,先以一个默认的频度访问页面,如果发现页面持续不更新,就逐步降低这个频度;反之亦然。

礼貌性策略

爬虫当然可以尽可能快地爬取数据,但是我们需要考虑网站的性能压力,已经对网络资源的消耗。

有一个 robots exclusion协议,指定了爬虫应该怎样访问网站的资源,哪些可以访问,哪些不可以访问。这个协议并不是强制的,但是已经是事实上的标准。比如,Crawl-delay参数,就可以定义每连续两次的请求,至少需要间隔多少秒。

以本网站的robots.txt为例:

User-agent: *
Disallow: /wp-admin/
Disallow: /wp-includes/

Sitemap: http://www.raychase.net/sitemap.xml.gz

其中的User-agent表示对爬虫类型没有限制,Disallow两行指定了哪些URL是不允许搜索引擎抓取的;Sitemap则是一个xml格式的网站地图:

<url>
  <loc>http://www.raychase.net/</loc>
  <lastmod>2013-05-25T16:32:13+00:00</lastmod>
  <changefreq>daily</changefreq>
  <priority>1.0</priority>
</url>
<url>
  <loc>http://www.raychase.net/1374</loc>
  <lastmod>2013-05-19T14:46:19+00:00</lastmod>
  <changefreq>monthly</changefreq>
  <priority>0.2</priority>
</url>

指定了网站有哪些页面,更新频率和权重各是多少。如果有些页面没有明显的直接链接抵达,通过sitemap的形式可以告知爬虫去抓取。如果你很讨厌某个搜索引擎,你可以这样指定(我只是举例而已,百度除了假药假广告侵权信息管制主观性过滤以外也是做了一些好事的 -_-~):

User-agent: Baiduspider

Disallow: /

网页深度

通常,越是深的链接,重要性越低,数量也越大。对于爬虫来说,越深的链接往往价值越小。在大多数情况下,我们不需要所有的信息,这时候需要控制合理的网页深度,价值高的网站可以深度适当大一些。

互联网即数据库

以前 我曾经介绍过YQL,一种像SQL查询数据库一样查询互联网网页数据的语言,你也可以在这个 YQL控制台自己试试:

select * from flickr.photos.search where text="Cat" and api_key="your key here" limit 10

这是一个“get 10 flickr “cat” photos”的例子。

再比如:

select * from html where url="http://finance.yahoo.com/q?s=yhoo" and xpath='//div[@id="yfi_headlines"]/div[2]/ul/li/a'

如果你看得懂XPATH表达式的话,这一定很清楚。它可以以普通HTTP API的方式暴露出来:

http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22http%3A%2F%2Ffinance.yahoo.com%2Fq%3Fs%3Dyhoo%22%20and%20xpath%3D'%2F%2Fdiv%5B%40id%3D%22yfi_headlines%22%5D%2Fdiv%5B2%5D%2Ful%2Fli%2Fa'&format=json&diagnostics=true&callback=cbfunc

在很多情况下,我们需要的并不是宽泛的信息,而是明确地知道自己需要什么信息,譬如某网站总是显示自己关心的信息,那么就可以借用它来定时爬取特定的页面(比如我以前干过这样的事:一场NBA比赛结束了,我没有看,但是我很想尽快地看到比赛录像,于是每隔几分钟就去爬取一个论坛比赛下载的帖子汇总页面,当“马刺”那个关键词出现的时候,我就去看一下是不是有比赛下载了。当然,你可以做得更好,写一个脚本让整个下载过程自动化完成,这样你就可以安心上班了,等回到家的时候,比赛已经下载完毕等你去看了)。现在这样的事情可以通过上面的HTTP API链接更方便地完成了。

完成整个过程以后,你一定会有这样的体会,互联网其实就是一个硕大的数据库(不管URI的定义是否符合RESTful风格,它最多只能说是数据是不是能够以符合某种统一格式的方式来获取)。

  1. HTML、RSS、PDF……这些只是不同的数据格式而已,和内容无关,获取这些不同格式不同地址数据的组件可以叫做requester;
  2. XPATH、CSSPath……这些是针对不同数据,去解析这些数据,指定有用信息的路径表达式,解析这些数据的组件被称为parser;
  3. 存储每一内容条目使用哪个requester和哪个parser的配置,汇总在一个configuration的组件内;
  4. 现在,还需要一个调度器scheduler管理若干个线程(或进程)根据configuration去爬取数据了;
  5. 数据爬取完成后持久化到存储组件storage中。

有了上面这5个组件,一个特定信息的爬取程序就完成了,和一个传统意义上的网络爬虫相比,它更加简单,也不需要解析HTML链接含义的过程。

另外,值得注意的是,有时候网站会做反爬虫机制,与其去猜它反爬虫的规则,还不如通过脚本启动一个浏览器去请求页面。还有,页面之间的关联关系有时并不能够从<a href=”xxx”>这样的链接中发现,有时是通过JavaScript的Ajax请求等等实现,这种情况下的链接关系对网络爬虫并不友好,也可以通过启动一个真实的浏览器请求去获取。

Java有名的开源网络爬虫包括 HeritrixNutch,后续我再详细介绍一下。

文章系本人原创,转载请保持完整性并注明出自 《四火的唠叨》

分享到:
你可能也喜欢:

相关 [网络爬虫] 推荐:

网络爬虫

- - 四火的唠叨
文章系本人原创,转载请保持完整性并注明出自 《四火的唠叨》. 最近在写一个程序,去爬热门事件和热门关键词网站上的数据. 网络爬虫也叫做网络蜘蛛,是一种互联网机器人,把需要的网页撷取下来,组织成适当格式存储. 它是搜索引擎的重要组成部分,虽然从技术实现上来说,它的难度往往要小于对于得到的网页信息的处理.

开源Python网络爬虫框架Scrapy

- - 互联网实践
所谓网络爬虫,就是一个在网上到处或定向抓取数据的程序,当然,这种说法不够专业,更专业的描述就是,抓取特定网站网页的HTML数据. 不过由于一个网站的网页很多,而我们又不可能事先知道所有网页的URL地址,所以,如何保证我们抓取到了网站的所有HTML页面就是一个有待考究的问题了. 一般的方法是,定义一个入口页面,然后一般一个页面会有其他页面的URL,于是从当前页面获取到这些URL加入到爬虫的抓取队列中,然后进入到新新页面后再递归的进行上述的操作,其实说来就跟深度遍历或广度遍历一样.

Webmagic 一个网络爬虫工具包

- - 行业应用 - ITeye博客
webmagic是一个开源的Java垂直爬虫框架,目标是简化爬虫的开发流程,让开发者专注于逻辑功能的开发. webmagic的核心非常简单,但是覆盖爬虫的整个流程,也是很好的学习爬虫开发的材料. 作者曾经进行过一年的垂直爬虫的开发,webmagic就是为了解决爬虫开发的一些重复劳动而产生的框架. web爬虫是一种技术,webmagic致力于将这种技术的实现成本降低,但是出于对资源提供者的尊重,webmagic不会做反封锁的事情,包括:验证码破解、代理切换、自动登录、抓取静态资源等.

搜索引擎-信息检索实践—网络爬虫

- - CSDN博客互联网推荐文章
网络爬虫有两个任务:下载页面和发现URL. 1.从请求队列中取出URL,下载对应页面,解析页面,找到链接标签. 2.网络爬虫发现了没有遇到过的URL,将其加入请求队列. 网络爬虫使用礼貌策略(politeness policy):. 网络爬虫不会在特定的网络服务器上一次抓取多个页面,在同一个网络服务器的两次请求之间,网络爬虫会等待一定时间.

基于Nutch+Hadoop+Hbase+ElasticSearch的网络爬虫及搜索引擎

- - zzm
网络爬虫架构在Nutch+Hadoop之上,是一个典型的分布式离线批量处理架构,有非常优异的吞吐量和抓取性能并提供了大量的配置定制选项. 由于网络爬虫只负责网络资源的抓取,所以,需要一个分布式搜索引擎,用来对网络爬虫抓取到的网络资源进行实时的索引和搜索. 搜 索引擎架构在ElasticSearch之上,是一个典型的分布式在线实时交互查询架构,无单点故障,高伸缩、高可用.

【网络爬虫之JSOUP使用简介】解析一个body片断

- - CSDN博客编程语言推荐文章
假如你有一个HTML片断 (比如. 一个 div 包含一对 p 标签; 一个不完整的HTML文档) 想对它进行解析. 这个HTML片断可以是用户提交的一条评论或在一个CMS页面中编辑body部分. Jsoup.parseBodyFragment(String html)方法.. parseBodyFragment 方法创建一个空壳的文档,并插入解析过的HTML到 body元素中.

【网络爬虫之JSOUP使用简介】解析一个HTML字符串

- - CSDN博客编程语言推荐文章
来自用户输入,一个文件或一个网站的HTML字符串,你可能需要对它进行解析并取其内容,或校验其格式是否完整,或想修改它. jsonu能够帮你轻松解决这些问题. Jsoup.parse(String html) 方法或. Jsoup.parse(String html, String baseUri)示例代码:.

【网络爬虫之JSOUP使用简介】入门:解析和遍历一个HTML文档

- - CSDN博客互联网推荐文章
jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容. 它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据. 从一个URL,文件或字符串中解析HTML;. 使用DOM或CSS选择器来查找、取出数据;. 可操作HTML元素、属性、 文本;.

网络爬虫框架scrapy介绍及应用——抓取新浪新闻的标题内容评论

- - CSDN博客综合推荐文章
开始这篇博文之前,调研了相关的爬虫方法,简单罗列冰山一角. 手动编写爬虫,httpclient 是常用工具. 常见的请求方式有httpget 和httppost. http://www.yeetrack.com/?p=779 这个教程很全面. httpclient 对js 的支持比较差,有时候需要使用htmlunit 或者selenium.