IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

聚焦爬虫:定向抓取系统的实现方法

标点符 2011-11-21 00:15:01 累计浏览 6,010 次
本机暂存

    网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列直到满足系统的一定停止条件。聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。另外,所有被爬虫抓取的网页将会被系统存贮,进行一定的分析、过滤,并建立索引,以便之后的查询和检索;对于聚焦爬虫来说,这一过程所得到的分析结果还可能对以后的抓取过程给出反馈和指导。

    相对于通用网络爬虫,聚焦爬虫还需要解决三个主要问题:

  • 对抓取目标的描述或定义;
  • 对网页或数据的分析与过滤;
  • 对URL的搜索策略。
  •     抓取目标的描述和定义是决定网页分析算法与URL搜索策略如何制订的基础。而网页分析算法和候选URL排序算法是决定搜索引擎所提供的服务形式和爬虫网页抓取行为的关键所在。这两个部分的算法又是紧密相关的。

        以下内容来自淘宝搜索引擎博客,应该是一淘网的具体实现方案。系统主要用到linux+mysql+redis+django+scrapy+webkit,其中scrapy+webkit作为抓取端,redis作为链接库存储,mysql作为网页信息存储,django作为爬虫管理界面,快速实现分布式抓取系统的原型。

        名词解析:

  • 抓取环:抓取环指的是spider在存储中获取url,从互联网上下载网页,然后将网页存储到数据库里面,最后在从存储里面获取下一个URL的一个流程。
  • Linkbase:链接库的存储模块,包含一般的链接信息;是抓取系统的核心,使用redis存储。
  • XPATH:一门在 XML 文档中查找信息的语言,XPath 可用来在 XML 文档中对元素和属性进行遍历, 是 W3C XSLT 标准的主要元素。使用XPATH以及相关工具lib进行链接抽取和信息抽取。
  • XPathOnClick:一个chrome的插件,支持点击页面元素,获取XPATH路径,用于编辑配置模板。
  • Redis:一个开源的KV的内存数据库,具备很好的数据结构的特征和很高的存取性能。用于存储linkbase信息
  • Django:爬虫管理工具,用于模板配置,系统监控反馈。Django在这里主要是用来管理一个数据库,使用Admin功能。
  • Pagebase:页面库,主要是存储网页抓取的结果,以及页面抽取的结果,和dump交互,使用mysql实现。
  • Scrapy:一个开源的机遇twisted框架的python的单机爬虫,该爬虫实际上包含大多数网页抓取的工具包,用于爬虫下载端以及抽取端。
  • 列表页:指的商品页面之外的所有页面
  • 详情页:比如商品B2C的抓取中,特指商品页面,比如:http://item.tmall.com/item.htm?id=10321272374
  •     系统架构

        一:存储 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,提交到抓取模块的待抓取队列,启动抓取,抓取完成之后对新链接进行抽取,最后进入等待抓取的队列里面。

        调度系统的基本配置:

  • 频率(间隔多少秒)
  • 各个抓取列表的选取比例:get_detail,mod_detail,get_list,mod_list
  • 链接抽取:抽取页面的链接,进行除重,对于新的链接,插入到待抓取列表里
  • 内容抽取:按照模块的配置XPATH,抽取页面信息,并写入到pagebase中。
  • 离线调度:按照更新的比例,从crawled_set里面,定期选取url进入Mod队列里面进行刷新。
  •     三:抓取模块:

        抓取模块是抓取的必要条件,抓取模块来说,重要的是应付互联网上各式的问题,以及如何实现对对方站点的ip平衡,当然,这块是和调度系统的紧密结合的,对于抓取模块而言,本文主要使用scrapy工具包里面的下载模块。

        首先,抓取模块从linkbase获取对应站点的抓取url,进行页面下载,然后将页面信息写回到pipeline中,并完成链接抽取和页面抽取,同时调用调度模块,插入到linkbase和pagebase中。

        下载端设计:

  • IP:每台机器需要配置多个物理公网IP,下载的时候,随机选择一个IP下载
  • 抓取频度调整:读取配置文件,按照配置文件的抓取频率进行选取url
  •     四:配置界面:

        配置界面主要是对抓取系统的管理和配置,包括:站点feed、页面模块抽取、报表系统的反馈等等。

        类似于通用的抓取架构,本文提到的抓取系统架构如下图:

        原图已失效

        一个完整的抓取数据流:

  • 用户提供种子URL
  • 种子URL进入linkbase中新URL队列中
  • 调度模块选取url进入到抓取模块的待抓取队列中
  • 抓取模块读取站点的配置文件,按照执行的频率进行抓取
  • 抓取的结果返回到pipeline接口中,并完成连接的抽取
  • 新发现的连接在linkbase里面进行dedup,并push到linkbase的新URL模块里面
  • 调度模块选取url进入抓取模块的待抓取队列,goto 4
  • end
  •     五、系统扩展

        本文提到的抓取系统,核心是调度和存储模块;其中,抓取,存储,调度都是通过数据进行交互的,因此,模块之间可以任意平行扩展,对于系统规模来说,只需要平行扩展mysql和redis存储服务集群以及抓取集群即可。当然,简单的扩展会带来一些问题:比如垃圾列表页的泛滥,链接库的膨胀等等问题,这些问题后续在讨论吧。

    同分类推荐文章

    1. 对基本有序的序列排序算法 (2026-06-11 17:46:49)
    2. Four Levels Of Customer Understanding (2026-05-22 21:00:00)
    3. 除法的意义 (2026-04-12 20:52:17)

    查看更多 算法 文章 →

    建议继续学习

    1. 红黑树并没有我们想象的那么难(上) (累计阅读 21,493)
    2. 为什么算法这么难? (累计阅读 12,394)
    3. 浅谈MySQL索引背后的数据结构及算法 (累计阅读 11,900)
    4. 加州求职记 (累计阅读 11,560)
    5. 海量数据面试题举例 (累计阅读 11,111)
    6. 基于Redis构建系统的经验和教训 (累计阅读 10,519)
    7. 谷歌(Google)2011年校园招聘笔试题 (累计阅读 9,571)
    8. 浅谈redis数据库的键值设计 (累计阅读 9,352)
    9. 关于使用STL的红黑树map还是hashmap的问题 (累计阅读 8,871)
    10. 再谈“我是怎么招聘程序员的” (累计阅读 8,789)