Python: 聚焦爬虫:定向抓取系统的实现方法
May 29, 2015
网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列直到满足系统的一定停止条件。聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。另外,所有被爬虫抓取的网页将会被系统存贮,进行一定的分析、过滤,并建立索引,以便之后的查询和检索;对于聚焦爬虫来说,这一过程所得到的分析结果还可能对以后的抓取过程给出反馈和指导。
相对于通用网络爬虫,聚焦爬虫还需要解决三个主要问题:
抓取目标的描述和定义是决定网页分析算法与URL搜索策略如何制订的基础。而网页分析算法和候选URL排序算法是决定搜索引擎所提供的服务形式和爬虫网页抓取行为的关键所在。这两个部分的算法又是紧密相关的。
以下内容来自淘宝搜索引擎博客,应该是 一淘网的具体实现方案 。系统主要用到linux+mysql+redis+django+scrapy+webkit,其中scrapy+webkit作为抓取端,redis作为链接库存储,mysql作为网页信息存储,django作为爬虫管理界面,快速实现分布式抓取系统的原型。
名词解析:
系统架构
一:存储 redis+mysql
链接库(linkbase)是抓取系统的核心,基于性能和效率的考虑,本文采用基于内存的redis和磁盘的mysql为主,对于linkbase主要是存储抓取必须的链接信息,比如url,anchor,等等;对于mysql,则是存放抓取的网页,便于后续的抽取和处理。
a) PageBase:使用Mysql分库分表,存放网页,如下图:
b)Linkbase:使用Redis集群,存储linkbase信息。
几个基本的数据结构:
抓取队列(candidate list)分为待抓取的url队列和更新的url队列;队列存放urlhash,使用redis的list数据结构,对于新提取的url,push到对应的列表里面,对于spider抓取模块,从list pop得到。对于一个站点而言,抓取队列有两种类型:列表页抓取队列和详情页抓取队列。
链接库(linkbase)链接库实际上是存储链接信息的DB;Key是urlhash,Value是linkinfo,包含url,purl,anchor,xpath。。。;在redis使用hash存储,直接存放在redis的里面。KV链接库,不区分页面类型。
已抓取集合(crawled_set)已抓取集合指的是当前已经下载的页面的urlhash,存放已经抓取的网页,使用redis的set实现,set的key是urlhash,score是时间戳,已抓取集合主要是用来记录哪一些页面已经抓取和抓取的时间,用于后续的更新页面调度以及抓取信息的统计。同抓取队列一样,每一个站点有两种类型的已抓取集合,详情页和列表页。
二:调度模块:
调度模块是抓取系统的关键,调度系统的好坏决定了抓取系统的效率;这块是主要是在redis linkbase之上的数据结构,主要有抓取队列、抓取集合、抓取优先级等等数据结构组成;对于一个抓取循环来说:获取URL,提交到抓取模块的待抓取队列,启动抓取,抓取完成之后对新链接进行抽取,最后进入等待抓取的队列里面。
调度系统的基本配置:
三:抓取模块:
抓取模块是抓取的必要条件,抓取模块来说,重要的是应付互联网上各式的问题,以及如何实现对对方站点的ip平衡,当然,这块是和调度系统的紧密结合的,对于抓取模块而言,本文主要使用scrapy工具包里面的下载模块。
首先,抓取模块从linkbase获取对应站点的抓取url,进行页面下载,然后将页面信息写回到pipeline中,并完成链接抽取和页面抽取,同时调用调度模块,插入到linkbase和pagebase中。
下载端设计:
四:配置界面:
配置界面主要是对抓取系统的管理和配置,包括:站点feed、页面模块抽取、报表系统的反馈等等。
类似于通用的抓取架构,本文提到的抓取系统架构如下图:
一个完整的抓取数据流:
五、系统扩展
本文提到的抓取系统,核心是调度和存储模块;其中,抓取,存储,调度都是通过数据进行交互的,因此,模块之间可以任意平行扩展,对于系统规模来说,只需要平行扩展mysql和redis存储服务集群以及抓取集群即可。当然,简单的扩展会带来一些问题:比如垃圾列表页的泛滥,链接库的膨胀等等问题,这些问题后续在讨论吧。
0 Comments