CN103475687B - 用于下载网站数据的分布式方法和系统 - Google Patents
用于下载网站数据的分布式方法和系统 Download PDFInfo
- Publication number
- CN103475687B CN103475687B CN201310198673.8A CN201310198673A CN103475687B CN 103475687 B CN103475687 B CN 103475687B CN 201310198673 A CN201310198673 A CN 201310198673A CN 103475687 B CN103475687 B CN 103475687B
- Authority
- CN
- China
- Prior art keywords
- download
- website
- list
- time
- module
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Expired - Fee Related
Links
Landscapes
- Information Transfer Between Computers (AREA)
Abstract
本发明提供了用于下载网站数据的分布式方法和系统。该方法包括以下步骤:设定一个或多个下载组;在数据库中针对每个下载组维护相应的网站列表;一个或多个下载模块中的每个下载模块根据针对与其相关联的下载组所维护的网站列表来获取相应网站的一个或多个下载队列;以及所述每个下载模块根据所述一个或多个下载队列来进行下载。
Description
技术领域
本发明总体上涉及分布式数据下载,更具体地涉及用于下载网站数据的分布式方法和系统。
背景技术
在当今的搜索引擎领域中,为了更快速有效地对互联网上的网页进行搜索,通常需要由搜索引擎提供商来预先从各个网站上抓取/爬取/下载(在下文中,这些术语可作为同义词互换使用)各种网页/应用程序/音频/视频等并进行分析。为了实现该网页抓取,不可避免地要用到各种网页抓取程序(也被称为网络爬虫、网络蜘蛛等,下文中统称为网络爬虫)。
现有的网络爬虫一般由一些起始地址开始下载网页,然后通过解析所下载的页面内容来决定后续爬取的页面。通常需要在爬虫程序内实现一个爬取队列,用于存放起始地址与解析出来的后续爬取地址。此外,还需要实现一个用于存放下载过的页面地址的去重过滤器,以避免重复爬取。
与单机的爬虫程序相比,可同时部署在多个节点上的分布式网络爬虫在计算机硬件资源和/或网络带宽资源的使用以及与ip、地域有关问题的处理上能够更加灵活。现有的分布式网络爬虫通常通过共享爬取队列和去重过滤器来实现。
然而,现有的爬虫系统至少存在以下问题:(1)不支持使用不同的下载配置来下载不同类型的数据;(2)其去重过滤器不支持有效期,即,其不支持对一些会更新的网页进行重复爬取;(3)不支持对爬取规则的设定以及对JavaScript(下文中简称为JS)的分析。
此外,现有的分布式爬虫系统还至少存在以下问题:(1)难以统一部署和配置,由于分布式爬虫系统通常部署在多台计算机上,因此对各个爬虫节点(模块)进行集中管理和统一配置非常困难。特别地,在需要对多个网站进行爬取的时候,常常需要在开始、停止爬取网站时登录爬虫服务器,进行修改配置、启动/停止相关进程等操作。当网站数量较大时,这些过程变得非常繁琐且容易出错;(2)难以设置针对特定网站的整体爬取间隔,通常需要控制网络爬虫对网站的访问间隔,以避免影响网站正常运转,减少对网站造成太大的负担,然而现有技术仅能在单个爬虫程序上对自身的爬取间隔进行限制,无法将所有分布式爬虫节点作为一个整体来进行控制,换言之,尽管可以限制单个爬虫对同一网站的各自的访问频率,但是难以避免出现很多爬虫同时或几乎同时访问该同一网站的情况,在该情况下,网站的正常运转受到了突发访问高峰的干扰,严重时有可能使网站宕机或下线;以及(3)难以收集统计信息,无法直接获得分布式爬虫的总体统计信息,通常需要另外搭建一套日志系统来实现此功能。
发明内容
因此,本发明提供了至少解决上述技术问题的用于下载网站数据的分布式方法和系统。
具体地,根据本发明的第一方案,提供了一种用于下载网站数据的分布式方法。该方法包括以下步骤:a)读取起始地址列表中的一个或多个地址,并将所述一个或多个地址存入在数据库中维护的多个下载队列中的至少一个下载队列,其中,所述多个下载队列至少包括第一下载队列和第二下载队列,且各个下载队列对应于不同类型的数据;b)根据所述多个下载队列来分别下载多个类型的数据;c)从根据所述第一下载队列下载的数据中解析出要下载的后续地址;d)判断所述后续地址属于哪个下载队列;e)根据步骤d)中的判断结果,将所述后续地址存入相应下载队列中;以及f)重复上述步骤b)至e),直到满足预定条件为止。
在一些实施例中,步骤b)包括:按照在所述数据库中集中维护的针对各个网站的下载间隔,根据相应下载队列中的记录,从相应网站下载数据。
在一些实施例中,所述第一下载队列是网页下载队列,以及所述第二下载队列是应用下载队列。
在一些实施例中,针对每个要下载的网站,预定义由多个下载模块统一使用的、并针对所述网站的不同页面类型单独规定的一条或多条爬取规则。
在一些实施例中,步骤d)包括:当所述爬取规则包括指示所述后续地址的类型的第一属性时,根据所述第一属性来判断所述后续地址属于哪个下载队列。
在一些实施例中,步骤d)还包括:当所述爬取规则不包括指示所述后续地址的类型的第一属性时,判断所述后续地址属于第二下载队列。
在一些实施例中,步骤e)包括:进一步判断所述后续地址是否满足由所述爬取规则中的第二属性所定义的正则表达式,如果满足所述正则表达式,则将作为所述后续地址与所述正则表达式匹配的结果的各字符串拼接为要存入相应下载队列中的地址,否则跳过所述后续地址。
在一些实施例中,步骤c)包括:根据所述爬取规则中用于描述后续地址的字符串构成特征的第三属性,从下载的数据中解析出要下载的后续地址。
在一些实施例中,所述第三属性是xpath表达式。
在一些实施例中,步骤b)包括:从第一下载队列中读取一条记录;使用在所述数据库中维护的第一去重列表,对所述记录进行去重;以及根据所述记录来下载相应数据。
在一些实施例中,对所述记录进行去重的步骤包括:当确定所述记录与所述第一去重列表中的记录匹配时,跳过所述记录并从所述第一下载队列中读取下一条记录。
在一些实施例中,在步骤e)之前,所述方法还包括以下步骤:使用所述记录中的地址来更新所述第一去重列表;以及步骤e)包括:在所述后续地址属于所述第一下载队列的情况下,使用更新后的所述第一去重列表对所述后续地址去重,并将其存入所述第一下载队列;以及在所述后续地址属于所述第二下载队列的情况下,使用在所述数据库中维护的第二去重列表对所述后续地址去重,相应更新所述第二去重列表,并将其存入所述第二下载队列。
在一些实施例中,步骤b)包括:按优先级从所述第二下载队列中读取待下载地址;使用在所述数据库中维护的第三去重列表对所述待下载地址进行去重;对由所述待下载地址指向的数据进行下载;以及更新所述第三去重列表。
在一些实施例中,步骤b)还包括:对已下载的数据进行检查;计算已下载的数据的数字摘要;基于所述数字摘要,使用在所述数据库中维护的第四去重列表对已下载的数据进行去重;更新所述第四去重列表;以及将所述已下载的数据存入文件系统中。
在一些实施例中,所述第一去重列表、所述第二去重列表和所述第三去重列表中的每条记录均包括有效期,当使用各个去重列表对相应地址进行去重并且在去重列表中存在与相应地址匹配的记录时,所述方法包括以下步骤:判断所述记录的有效期是否已到期,如果已到期,则不对相应地址进行去重,如果未到期,则对相应地址进行去重。
在一些实施例中,所述爬取规则还包括第四属性,当所述第四属性的值为“真”时,通过记录对包括所述第四属性在内的所述爬取规则的使用的次数,来识别当前下载的链接在相应网站的应用列表的第几页上。
在一些实施例中,在更新所述第一去重列表、所述第二去重列表或所述第三去重列表时,在当前下载的链接在应用列表的预定页数的页面上的情况下,与当前下载的链接在应用列表的预定页数之后的页面上的情况下相比,将去重列表中对应记录的有效期设置为更大。
在一些实施例中,所述预定页数小于等于5页。
在一些实施例中,由所述数据库来提供与网站数据下载相关的统计信息。
在一些实施例中,所述统计信息包括以下一项或多项:所述多个下载队列的当前长度、指定时间段内各个去重列表的长度、或各个去重列表的总长度。
在一些实施例中,所述数据库是key-value型数据库。
在一些实施例中,所述数据库是Redis数据库。
在一些实施例中,所述预定条件是所有下载队列为空、达到预定爬取深度、或二者的组合。
根据本发明的第二方面,提供了一种用于下载网站数据的分布式系统。该系统包括:控制器,读取起始地址列表中的一个或多个地址,并将所述一个或多个地址存入在数据库中维护的多个下载队列中的至少一个下载队列;数据库,用于维护多个下载队列,其中,所述多个下载队列至少包括第一下载队列和第二下载队列,且各个下载队列对应于不同类型的数据;多个下载模块,用于根据所述多个下载队列来分别下载多个类型的数据,从根据所述第一下载队列下载的数据中解析出要下载的后续地址,判断所述后续地址属于哪个下载队列,根据所述判断的结果,将所述后续地址存入相应下载队列中;以及重复上述过程,直到满足预定条件为止。
在一些实施例中,所述多个下载模块被进一步配置为:按照在所述数据库中集中维护的针对各个网站的下载间隔,根据相应下载队列中的记录,从相应网站下载数据。
在一些实施例中,所述第一下载队列是网页下载队列,以及所述第二下载队列是应用下载队列。
在一些实施例中,针对每个要下载的网站,预定义由多个下载模块统一使用的、并针对所述网站的不同页面类型单独规定的一条或多条爬取规则。
在一些实施例中,所述下载模块被配置为:当所述爬取规则包括指示所述后续地址的类型的第一属性时,根据所述第一属性来判断所述后续地址属于哪个下载队列。
在一些实施例中,所述下载模块还被配置为:当所述爬取规则不包括指示所述后续地址的类型的第一属性时,判断所述后续地址属于第二下载队列。
在一些实施例中,所述下载模块被配置为:进一步判断所述后续地址是否满足由所述爬取规则中的第二属性所定义的正则表达式,如果满足所述正则表达式,则将作为所述后续地址与所述正则表达式匹配的结果的各字符串拼接为要存入相应下载队列中的地址,否则跳过所述后续地址。
在一些实施例中,所述下载模块被配置为:根据所述爬取规则中用于描述后续地址的字符串构成特征的第三属性,从下载的数据中解析出要下载的后续地址。
在一些实施例中,所述第三属性是xpath表达式。
在一些实施例中,所述下载模块被配置为:从第一下载队列中读取一条记录;使用在所述数据库中维护的第一去重列表,对所述记录进行去重;以及根据所述记录来下载相应数据。
在一些实施例中,所述下载模块还被配置为:当确定所述记录与所述第一去重列表中的记录匹配时,跳过所述记录并从所述第一下载队列中读取下一条记录。
在一些实施例中,所述下载模块被配置为:使用所述记录中的地址来更新所述第一去重列表;在所述后续地址属于所述第一下载队列的情况下,使用更新后的所述第一去重列表对所述后续地址去重,并将其存入所述第一下载队列;以及在所述后续地址属于所述第二下载队列的情况下,使用在所述数据库中维护的第二去重列表对所述后续地址去重,相应更新所述第二去重列表,并将其存入所述第二下载队列。
在一些实施例中,所述下载模块还被配置为:按优先级从所述第二下载队列中读取待下载地址;使用在所述数据库中维护的第三去重列表对所述待下载地址进行去重;对由所述待下载地址指向的数据进行下载;以及更新所述第三去重列表。
在一些实施例中,所述下载模块还被配置为:对已下载的数据进行检查;计算已下载的数据的数字摘要;基于所述数字摘要,使用在所述数据库中维护的第四去重列表对已下载的数据进行去重;更新所述第四去重列表;以及将所述已下载的数据存入文件系统中。
在一些实施例中,所述第一去重列表、所述第二去重列表和所述第三去重列表中的每条记录均包括有效期,当使用各个去重列表对相应地址进行去重并且在去重列表中存在与相应地址匹配的记录时,所述下载模块还被配置为:
判断所述记录的有效期是否已到期,如果已到期,则不对相应地址进行去重,如果未到期,则对相应地址进行去重。
在一些实施例中,所述爬取规则还包括第四属性,当所述第四属性的值为“真”时,通过记录对包括所述第四属性在内的所述爬取规则的使用的次数,来识别当前下载的链接在相应网站的应用列表的第几页上。
在一些实施例中,在更新所述第一去重列表、所述第二去重列表或所述第三去重列表时,在当前下载的链接在应用列表的预定页数的页面上的情况下,与当前下载的链接在应用列表的预定页数之后的页面上的情况下相比,所述下载模块将去重列表中对应记录的有效期设置为更大。
在一些实施例中,所述预定页数小于等于5页。
在一些实施例中,由所述数据库来提供与网站数据下载相关的统计信息。
在一些实施例中,所述统计信息包括以下一项或多项:所述多个下载队列的当前长度、指定时间段内各个去重列表的长度、或各个去重列表的总长度。
在一些实施例中,所述数据库是key-value型数据库。
在一些实施例中,所述数据库是Redis数据库。
在一些实施例中,所述预定条件是所有下载队列为空、达到预定爬取深度、或二者的组合。
根据本发明的第三方面,提供了一种用于下载网站数据的分布式方法。该方法包括以下步骤:设定一个或多个下载组,在数据库中针对每个下载组维护相应的网站列表;一个或多个下载模块中的每个下载模块根据针对与其相关联的下载组所维护的网站列表来获取相应网站的一个或多个下载队列;以及所述每个下载模块根据所述一个或多个下载队列来进行下载。
在一些实施例中,通过在启动所述下载模块时指定组名,将所述下载模块和与所述组名相关联的下载组相关联。
在一些实施例中,当在启动所述下载模块时未指定组名时,将所述下载模块与缺省下载组相关联。
在一些实施例中,所述网站列表中的记录均具有下次下载时间项,以及下载模块根据针对与其相关联的下载组所维护的网站列表来获取相应网站的一个或多个下载队列的步骤还包括:所述下载模块仅获取下次下载时间项的值小于当前时间的记录来获取相应网站的一个或多个下载队列。
在一些实施例中,所述一个或多个下载模块至少包括第一下载模块和第二下载模块,以及在获得网站列表的同时如下更新所述下次下载时间项的值:针对所述第一下载模块,所述下次下载时间项的值等于当前时间与爬取间隔之和;以及针对所述第二下载模块,所述下次下载时间项的值等于当前时间、下载超时时间、以及下载间隔之和。
在一些实施例中,所述爬取间隔是2秒。
在一些实施例中,所述下载间隔是10秒。
在一些实施例中,针对所述第二下载模块,在完成下载之后,使用当前时间与下载间隔之和再次更新所述下次下载时间项。
在一些实施例中,所述第一下载模块以固定时间间隔来获取网站列表。
在一些实施例中,所述第二下载模块在预定事件发生时获取网站列表,同时也以固定时间间隔来获取网站列表。
在一些实施例中,通过向网站列表中插入/移除记录来控制针对相应网站的下载的启动/停止。
在一些实施例中,该方法还包括:根据网站的结构设置爬取规则;根据所述爬取规则,使用与测试专用组相关联的下载模块来尝试下载所述网站的数据;检查下载到的数据,确认是否存在异常,如果存在异常,则在本地调试所述爬取规则并解决导致异常出现的问题;在确认数据正常之后,清除所述测试专用组;以及在目标组中正式启动相应下载模块来下载所述网站的数据。
在一些实施例中,该方法还包括:查询统计信息,检查是否存在网站数据的下载异常;如果存在异常,则停止发生异常的下载;根据针对下载异常的网站的爬取规则,使用与测试专用组相关联的下载模块来尝试下载所述网站的数据;检查下载到的数据,确认是否存在异常,如果存在异常,则在本地调试所述爬取规则并解决导致异常出现的问题;在确认数据正常之后,清除所述测试专用组;以及正式启动和与下载异常的网站相对应的下载组相关联的下载模块来重新下载所述网站的数据。
在一些实施例中,所述当前时间以所述数据库中的时间为准。
在一些实施例中,所述方法还包括:如果针对下载队列中的地址下载失败,则将所述地址以较低优先级置回所述下载队列中,以便重新调度下载。
根据本发明的第四方面,提供了一种用于下载网站数据的分布式系统。该系统包括:控制器,用于设定一个或多个下载组,数据库,用于针对每个下载组来维护相应的网站列表;以及一个或多个下载模块,每个下载模块用于根据针对与其相关联的下载组所维护的网站列表来获取相应网站的一个或多个下载队列,以及根据所述一个或多个下载队列来进行下载。
在一些实施例中,通过在启动所述下载模块时指定组名,将所述下载模块和与所述组名相关联的下载组相关联。
在一些实施例中,当在启动所述下载模块时未指定组名时,将所述下载模块与缺省下载组相关联。
在一些实施例中,所述网站列表中的记录均具有下次下载时间项,以及所述下载模块还被配置为:仅获取下次下载时间项的值小于当前时间的记录来获取相应网站的一个或多个下载队列。
在一些实施例中,所述一个或多个下载模块至少包括第一下载模块和第二下载模块,以及在获得网站列表的同时如下更新所述下次下载时间项的值:针对所述第一下载模块,所述下次下载时间项的值等于当前时间与爬取间隔之和;以及针对所述第二下载模块,所述下次下载时间项的值等于当前时间、下载超时时间、以及下载间隔之和。
在一些实施例中,所述爬取间隔是2秒。
在一些实施例中,所述下载间隔是10秒。
在一些实施例中,针对所述第二下载模块,在完成下载之后,使用当前时间与下载间隔之和再次更新所述下次下载时间项。
在一些实施例中,所述第一下载模块以固定时间间隔来获取网站列表。
在一些实施例中,所述第二下载模块在预定事件发生时获取网站列表,同时也以固定时间间隔来获取网站列表。
在一些实施例中,所述控制器通过向网站列表中插入/移除记录来控制针对相应网站的下载的启动/停止。
在一些实施例中,通过以下方式来部署针对网站的爬取规则:根据网站的结构设置爬取规则;根据所述爬取规则,使用与测试专用组相关联的下载模块来尝试下载所述网站的数据;检查下载到的数据,确认是否存在异常,如果存在异常,则在本地调试所述爬取规则并解决导致异常出现的问题;在确认数据正常之后,清除所述测试专用组;以及在目标组中正式启动相应下载模块来下载所述网站的数据。
在一些实施例中,通过以下方式来调整针对网站的爬取规则:查询统计信息,检查是否存在网站数据的下载异常;如果存在异常,则停止发生异常的下载;根据针对下载异常的网站的爬取规则,使用与测试专用组相关联的下载模块来尝试下载所述网站的数据;检查下载到的数据,确认是否存在异常,如果存在异常,则在本地调试所述爬取规则并解决导致异常出现的问题;在确认数据正常之后,清除所述测试专用组;以及正式启动和与下载异常的网站相对应的下载组相关联的下载模块来重新下载所述网站的数据。
在一些实施例中,所述当前时间以所述数据库中的时间为准。
在一些实施例中,所述下载模块还被配置为:如果针对下载队列中的地址下载失败,则将所述地址以较低优先级置回所述下载队列中,以便重新调度下载。
通过使用本发明提供的方法和系统,可以按照要获取的数据的类型,例如(但不限于):网页文件(例如,html、xhtml、shtml等等)、应用程序(例如,在Windows平台上运行的exe文件、针对Android系统的apk应用程序包等)、文档文件(例如,WORD文件、PDF文件等)、动态图像文件(例如,AVI文件、MP4文件等等)、静态图像文件(例如,JPG文件、BMP文件等等)、音频文件(MP3、WMA等等)、以及其他各种数据类型(例如,Flash等等),由爬虫(下载器)采用不同的下载和处理流程来进行处理。充分利用了这些不同类型数据在处理器/存储器资源和/或网络资源等方面上的不同特性。
此外,通过使用本发明提供的方法和系统,可以提供针对去重列表中任意记录的有效期,使得对一些可能会更新的网页的重复爬取成为可能。
此外,通过使用本发明提供的方法和系统,可以通过使用xpath表达式和正则表达式,在很大程度上处理了网页文件中以JS格式表达的网络地址的问题。
此外,通过使用本发明提供的方法和系统,支持由多个爬虫模块统一使用的、并针对不同页面类型单独提供的爬取规则,使得在简化了对多个爬虫模块的爬取规则的维护的同时,让爬取规则支持更为复杂的设置,以更方便地针对各个网站来设计爬取规则。特别地,通过让爬取规则支持翻页规则,使得用户可以针对不同页数来采取不同的爬取策略和更新去重列表的策略。
此外,通过使用本发明提供的方法和系统,借助专门的控制器和数据库来操作爬虫模块,包括:启动/停止/查看状态/修改配置等等,而无需在部署各个爬虫模块的节点上分别进行操作。
此外,通过使用本发明提供的方法和系统,借助数据库中统一维护的针对各个爬取/下载组维护的列表,可以对所有爬虫(下载器)的针对某一个网站的爬取间隔进行限制。此外,借助数据库中统一维护的爬取队列,支持多个分布式爬虫采用相同的爬取队列。
此外,通过使用本发明提供的方法和系统,借助针对数据库中维护的各个列表/队列的统计功能,可以获取相关统计信息,包括(但不限于):当前爬取队列/下载队列大小、以及总体/特定时间段内的爬取页面数/解析下载链接数/下载数/新文件数等。
换言之,通过使用本发明提供的方法和系统,可以解决或至少减轻现有技术所具有的前述技术问题。
附图说明
通过下面结合附图说明本发明的优选实施例,将使本发明的上述及其它目的、特征和优点更加清楚,其中:
图1示出了根据本发明的实施例的用于下载网站数据的示例分布式系统的简化框图;
图2示出了在图1所示的数据库中维护的一些示例数据结构的示意图;
图3~9示出了根据本发明的实施例的用于设计示例爬取规则的示例过程的屏幕截图;
图10示出了根据本发明的实施例的用于下载网站数据的分布式方法的示例的爬取部分的流程图;以及
图11示出了根据本发明的实施例的用于下载网站数据的分布式方法的示例的下载部分的流程图。
在本发明的所有附图中,相同或相似的结构均以相同或相似的附图标记来标识。
具体实施方式
下面参照附图对本发明的优选实施例进行详细说明,在描述过程中省略了对于本发明来说是不必要的细节和功能,以防止对本发明的理解造成混淆。以下,将结合特定的实施例来详细描述本发明的方法和系统。但是本领域技术人员应当理解:以下描述的各个特定实施例并不限制本发明的范围;相反地,应当将这些特定实施例理解为被包括在由所附权利要求限定的本发明的精神和范围中,且本领域技术人员可以在不脱离由所附权利要求限定的本发明的精神和范围的情况下,对本发明做出各种修改、添加、删除、或替换。
首先,参见图1,其示出了根据本发明的实施例的用于下载网站数据的示例分布式系统10的简化框图。分布式系统10包括:控制器110、数据库120、多个爬虫130_1~130_N(N代表爬虫的数目)、以及多个下载器140_1~140_M(M代表下载器的数目)。控制器110与数据库120相连,且数据库120与各个爬虫130_1~130_N和各个下载器140_1~140_M相连,形成以数据库120为中心的星型拓扑结构,进而控制器110可以通过数据库120来控制各个爬虫130_1~130_N和各个下载器140_1~140_M,且各个爬虫130_1~130_N和各个下载器140_1~140_M可以通过数据库120向控制器110反馈各种信息。当然,在另一些实施例中,控制器110可以与各个爬虫130_1~130_N和各个下载器140_1~140_M直接相连并通信。
在本实施例中,数据库120是key-value型数据库,更优选地,是Redis数据库。当然,数据库120也可以是其它key-value型数据库,例如(但不限于):Berkeley DB、MemCacheDB、BigTable、Dynamo、Tokyo Cabinet等等。此外,数据库120也可以是其它非key-value型数据库,例如(但不限于):MySQL、Microsoft SQL、Oracle RDBMS等。
然而,与传统的关系型数据库相比,key-value型数据库能够提供更高的查询速度、更大的数据容量、更高的并发数、更适合通过主键进行查询,因此优选地使用key-value型数据库为本发明的各个模块提供队列/列表/配置/数据文件的存储和管理等等。此外,由于Redis数据库提供了多种数据结构(包括字符串(string)、双向链表(list)、集合(set)、以及有序集合(zset)),因此其与其它key-value型数据库相比,更适于实现本发明的方法和系统。在下文中将描述通过这些数据结构,特别是有序集合(zset),来实现根据本发明的实施例的在数据库120中存储的各种数据结构。
为了方便对下文的理解,下面简要介绍一下zset的结构。zset是一个集合类的数据结构,其中每个元素均额外具有一个顺序属性(z值,又被称为score值)。可以在添加或修改元素的时候指定这一属性。每次指定后,zset会自动按新的z值来重新调整zset中各元素的顺序。可以跟据z值指定的顺序,以很高的效率对zset中的元素进行存取。更多细节可以参考zset的使用说明:http://redis.io/commands#sorted_set。
现在,返回图1,将继续描述分布式系统10。在本实施例中,分布式系统10主要用于对指定网站的网页和在网页中提供的应用程序进行下载,并对下载到的网页进行分析,从中提取出可供后续下载的网页和/或应用程序的地址。在另一示例中,分布式系统10也可以用于对其他类型的数据进行下载,例如对网页和在网页中提供的视频进行下载、分析等。在另一示例中,分布式系统10也可以用于对一种或三种以上的数据(例如,网页、应用程序、音频等)进行下载、分析等。
在分布式系统10中,控制器110通过数据库120提供的数据库接口来处理在数据库120中维护的各个数据结构等,从而间接地控制各个爬虫130_1~130_N和各个下载器140_1~140_M。
在本实施例中,爬虫130_1~130_N和下载器140_1~140_M是基于开源爬虫框架scrapy1.6开发的,但本发明的实施例不限于此,也可以使用其它爬虫程序。
因此,在图1所示的分布式系统10中,各个模块的主要功能和使用方式如表1所示。
表1
根据表1,可以看到,分布式系统10以数据库120为流程控制的核心,系统的各模块间相互独立,通过操作数据库120来交换信息。
接下来,将参照图2来说明在数据库120中维护的用于协调和控制各个爬虫130_1~130_N和各个下载器140_1~140_M的列表和队列的具体示例。参见图2,在数据库120中维护了以下数据结构:针对每个要下载的网站的爬取队列(第一下载队列)121_1~121_L(L代表要下载的网站数目,下同)和下载队列(第二下载队列)122_1~122_L、针对每个要下载的网站的爬虫去重列表(第一去重列表)123_1~123_L、解析去重列表(第二去重列表)124_1~124_L、下载去重列表(第三去重列表)125_1~125_L和文件去重列表(第四去重列表)126_1~126_L、针对每个要下载的网站的起始地址列表127_1~127_L、针对每个爬取/下载组的访问限制列表128_1~128_P(P代表爬取/下载组的数目)、针对网页的每个类型的类型配置列表129_1~129_Q(Q代表网页类型的数目)、针对每个网站的网站配置列表130_1~130_L、以及针对每个类型配置列表和网站配置列表的配置更新列表131。
接下来,将详细描述上述每个数据结构的格式以及用途。
(1)针对每个要下载的网站的爬取队列121_1~121_L和下载队列122_1~122_L
针对每个需要爬取的网站,在数据库120中各自维护一个爬取队列和一个下载队列,其用于保存待爬取/下载的网络地址。这两个队列均采用zset实现,这两个队列的键名可以分别通过“crawl_queue_”+“网站名”和“down_queue_”+“网站名”来指定。队列中每个成员(待处理地址)对应的z值为相应网络地址的抓取优先级(以下简称优先级)的负值。通过获取集合中z值最小的元素(通过zrange命令),即可取得队列中优先级最高的成员。
(2)针对每个要下载的网站的爬虫去重列表123_1~123_L、解析去重列表124_1~124_L、下载去重列表125_1~125_L和文件去重列表126_1~126_L
针对每个需要爬取的网站,在数据库120中维护了上述多种去重列表。这些去重列表均采用zset实现,键名通过“预设字符串”+“网站名”这种方式来指定(不同的去重列表采用不同的预设字符串)。去重列表中每个成员对应的z值为对应元素上次被处理时的时间戳。
对于不存在有效期(即,不需要重复爬取)的地址,通过判断列表中是否存在该元素(zrank命令)即可判断该元素是否重复。对于存在有效期的地址,通过zscore方法获取对应元素的z值,然后判断该时间戳+有效期是否大于当前时间,即可判断出该元素是否重复,在后文中将详细描述。
zset数据结构支持查询特定z值落在特定区间内的所有元素(通过zrangebyscore命令)。控制器110获取爬虫系统的统计信息时利用了该特性,在后文中将详细描述。
此外,由于分布式系统中各模块所在计算机的本地时间之间通常存在偏移量,为了保证与时间戳相关的流程的正常工作,分布式系统10可以统一采用数据库120所在的计算机上提供的时间作为基准值。各模块第一次获取时间时通过数据库120的数据库接口获取服务器系统时间(例如,通过time命令),并记录下该时间与自身系统时间的差值。之后每次需要使用时间戳时均通过获取自身系统时间(例如,通过命令time.time()),并加上记录下的差值作为实际时间。
当然,这只是一个可行的方式,并不意味着本发明受限于此。实际上,在各模块之间进行时间同步的方式还有很多,例如通过NTP(网络时间协议)在各服务器之间进行时间同步等。在下文中,为了说明的简单,假定各模块之间的时间是同步的,且因此不需要考虑时间同步的问题。
(3)针对每个要下载的网站的起始地址列表127_1~127_L
针对每个需要爬取的网站,在数据库120中维护一个对应的起始地址列表。该列表采用zset实现,键名为“start_url_”+“网站名”。起始地址列表中每个成员对应的z值为该地址下次可被推入爬取队列的最小时间。爬虫(或控制器或任何其他模块)以固定或可变时间间隔从该列表中取出z值小于当前时间(zrangebyscore命令)的成员,将其推入爬取队列,并将起始地址列表中对应项的z值更新为当前时间+有效期。
(4)针对每个爬取/下载组的访问限制列表128_1~128_P
可以将要下载的一个或多个网站进行分组,将它们分为爬取/下载组。针对每个爬取/下载组,在数据库120中维护一个对应的列表。该列表采用zset实现,键名分别为“crawl_group_”+“网站名”与“down_group_”+“网站名”。列表内各成员对应的z值为该网站允许下一次爬取/下载的时间。爬虫/下载器通过查询其所在的爬取/下载组的访问限制列表中的z值小于当前时间(通过例如zrangebyscore命令)的成员,即可取得需要爬取/下载的网站名称。通过该访问限制列表,可以针对不同的爬取/下载组来分别设置各自组针对特定网站的访问频率,从而更灵活有效地控制各个爬虫/下载器。
(5)针对网页的每个类型的类型配置列表129_1~129_Q、针对每个网站的网站配置列表130_1~130_L
针对每个类型配置/网站配置,在数据库120中维护一个String类型的值,其键名分别为“type_config_”+“类型名”与“spider_config_”+“网站名”,内容为配置文件中对应xml节点的字符串形式,下文将详细描述。
(6)针对每个类型配置列表和网站配置列表的配置更新列表131
该列表用于存放配置的更新信息,当已存在的类型配置/网站配置发生变化后,相应的信息将被存入该列表中,以通知各模块进行更新。该列表采用zset实现,键名为“config_update_list”。其成员为已更新的配置文件在数据库120中对应的键名,z值为更新时间。系统任意模块启动后,均会记录下启动时间作为最后更新时间。之后每隔一段固定时间(1000秒)检查一次该列表。若存在更新时间(z值)大于程序最后更新时间的成员,即将该成员对应的配置重新读入更新。检查完该列表后,将最后更新时间设置为当前时间,以避免重复更新。
此外,上述所有列表/队列的键名的命名规则不限于上述示例给出的字符串,其也可以是用于区别队列/列表的其他字符串。
接下来,将参照图3~9来详细描述用于设计示例爬取规则的示例过程。在本发明中,爬取规则用于指导爬虫(模块)如何爬取网站并解析出后续爬取/下载地址。在本示例中,针对软件下载类网站的特点,本系统通过将网页分类,对不同类型的页面采用不同的爬取规则进行爬取。当然,也可以针对其他类型的网站的特点对爬取规则进行设计,本发明不限于此。爬取规则主要通过xpath表达式来指定,并可使用正则表达式来过滤一些不希望爬取的页面。
具体地,在本实施例中,使用Firefox浏览器的Firebug插件以及Firepath插件来演示如何设计爬取规则的示例。当然也可以使用其他浏览器的其他xpath相关插件或使用其他开发界面或调试工具来演示设计爬取规则的过程。此外,在本实施例中,针对单一网站(“安极市场”)来设计爬取规则,但应当理解:也可以针对一个或多个网站来类似地设计爬取规则,只要其能实现相同的目的即可。
首先以网站“安极市场”为例,通常如下所述得到爬取规则。参见图3,爬虫从起始页http://apk.angeeks.com开始抓取页面,并将该页面的页面类型定义为“home”。通过基于xpath语法的表达式
//dd[@id=′vtit′]//a
来选取各主列表页作为下一个要爬取的页面类型“list_”。
表达式“//dd[@id=′vtit′]//a”的语义即表示选中当前网页中“定义列表”项(definition list,语法为“dd”)下所有的引用项(reference,语法为“a”),且这些定义列表项的属性“id”为字符串“vtit”。xpath的具体语法请参考xpath和html的使用说明,例如分别参见http://www.w3school.com.cn/h.asp和http://www.w3school.com.cn/xpath。
如图3所示,通过上述xpath表达式选中了“安极市场”主页上的抬头列表项,例如“首页”、“游戏”、“应用”等等,在网页中以虚线框来标识被选中的项。可以在图3的下半部分中看到提取出的列表项具有完全或部分的网页链接(地址)的形式,例如“../index.jsp”、“http://apk.angeeks.com/list/c-8.html”。请注意:此处的“首页”、“装机必备”、“机型专区”这三个主列表页链接并非我们所需要的下载列表页,为了减少不必要的爬取,可通过正则表达式(.*list.*)对提取出的地址进行进一步过滤,以选中链接中包含字符串“list”的链接,从而将“首页”、“装机必备”、“机型专区”等三个链接过滤掉。鉴于正则表达式的语法是本领域技术人员众所周知的,本申请将不再赘述。
这样,通过上述xpath表达式和正则表达式,选中了“游戏”、“应用”、“电子书”、“主题”和“壁纸”等五个页面。接下来,以“游戏”页面为例进行后续说明。参见图4,其示出了在游戏页面中进行的后续操作。具体地,如参照图3所述,将“游戏”、“应用”、“电子书”、“主题”和“壁纸”等五个主列表页面的页面类型定义为“list_”。尽管“list_”类型的页面也为(主)列表页,但由于希望能按时间顺序抓取程序包(例如,为了优先抓取最近更新的程序包),所以此类页面并不适合作为获取下载地址的列表页。当然,对于其他网站来说,有可能默认提供的页面就是按时间顺序排列的列表页,此时也就不需要图4所示的步骤。这应当完全取决于所要抓取的网站的具体设计。
返回图4,为了在“游戏”页面上选中“按更新时间排序”,使用以下xpath表达式
//div[@class=′mytak′]/p[last()]/a
来选取“按更新时间排序”链接,并将所获取的链接定义为“list”类型。如图4所示,在网页中以虚线框来标识被选中的项。
在选中“按更新时间排序”后,还需要两条爬取规则来进行后续操作。第一条爬取规则负责解析当前列表页面上所有要下载的应用软件的信息页(即,提供要下载的应用软件的相关信息以及下载链接的页面)。第二条爬取规则负责将当前列表页面翻到下一页,即负责获取下一个列表页面。
针对上述第一条爬取规则,参见图5,其示出了获取当前列表页面上所有待下载应用软件的信息页的步骤。此处,使用xpath表达式
//div[@class=′info′]/a
来获取类型被定义为“topic”的各待下载应用软件的页面。如图5所示,通过该xpath表达式选中了“游戏”页面上“按更新时间排序”模式下的各软件信息页,例如“Mechanical Zuma”、“职业桌球(中文版)”、“象棋巫师”等等,在网页中以虚线框来标识被选中的项。可以在图5的下半部分中看到提取出的信息页具有部分的网页链接(地址)的形式,例如“/soft/10119542.html”。当然,对于其他网站来说,信息页的网页地址不限于部分地址,其也可以是完全的地址,这完全取决于网站的具体设计。
针对上述第二条爬取规则,参见图6,其示出了获取当前列表页面上指向下一页的“>”按钮的网页地址的步骤。此处,使用xpath表达式
//div[@class=′pagenumt′]/a[last()-1]
来获取类型也被定义为“list”的下一个列表页。如图6所示,通过该xpath表达式选中了网页上的“>”按钮所对应的网页地址,在网页中以虚线框来标识被选中的项。因此,第二条爬取规则也被称为“翻页规则”。可以在图6的下半部分中看到提取出的列表页具有部分的网页链接(地址)的形式,例如“/list/c-8-2-1.html”。
这样,通过反复应用上述第一条爬取规则和第二条爬取规则,即可获得“安极市场”的“游戏”页面在“按更新时间排序”模式下的所有应用软件的信息页(下载页)的链接。需要注意的是,在根据上述第二条规则翻到最后一页时,由于使用上述xpath表达式获取到的地址实际上指向的还是最后一页(即,该时刻的当前页),因此将通过去重列表或其他终止手段(例如,另一条爬取规则或正则表达式等)来结束图6所示的解析过程,本发明不限于上述终止手段。当然,针对不同网站应当设计并使用相应的爬取规则。
接下来,将参照图7来详细描述如何在每个信息页上获取用于下载相应软件的地址。参见图7,其以软件“职业桌球(中文版)”为例,示出了通过xpath表达式来获取“职业桌球(中文版)”下载链接的步骤。在图7中,通过使用xpath表达式
//img[@src=″/images/wandoujiabutton.jpg″]/..
来获取软件的下载链接。通过该xpath表达式选中了网页上以虚线框来标识的“一键安装”按钮所对应的网页地址。可以在图7的下半部分中看到提取出的下载页具有完全网页链接(地址)的形式,例如“http://apk.angeeks.com/downloadAPK.do?soft_id=10119517”。
这样,通过图3~7所述的方法步骤,可以得出针对“安极市场”的各条爬取规则。根据这些爬取规则,可以由爬虫得到各个软件的按更新时间排序的应用下载列表,将其存入下载队列,并由下载器按照下载队列来进行下载。
此外,值得一提的是绝大部分应用软件下载页面在其软件的详细信息页(在本实施例中,“topic”页)上均会提供大量的软件相关信息,采用类似提取下载链接的方式(xpath表达式)可以很方便的将下载的软件包的相关信息一并获取。
接下来,为了通过配置文件来配置爬虫模块和下载模块,需要将上面针对特定网站生成的爬取规则加以规范化。例如,在以xml格式来定义配置文件的情况下,可以将上述爬取规则定义为配置文件中的一个spider节点。例如如下所示:
接下来详细解释该spider节点中各项的语义。
(1)spider节点
spider节点的“name”属性用于在本发明的系统内部表示网站的简称,针对图3~7所示的示例,可以将“name”属性赋值为“angeeks”(安极)。“channel”属性用于标识网站进而与后续系统对接。
(2)spider节点的start_url节点
start_url节点用于定义起始页。起始页可以有多个,因此也就可以存在多个start_url节点。在本实施例中,起始页类型默认为“home”,但是也可以通过为该节点增加“type”属性来指定其类型。在存在多个起始页时,也可分别指定类型。start_url节点的“url”属性表示该节点所指向的具体URL,在本示例中,起始页面只有一个,其页面地址即为“url”属性中的“http://apk.angeeks.com/”。
(3)spider节点的crawl_rule节点
crawl_rule节点用于定义单条爬取规则。其“from”属性指定了将该规则应用于哪种类型的页面,而“to”属性指定应用该规则后解析出来的地址指向的页面属于哪种类型。该属性忽略时解析出的地址将作为下载链接被提交给下载器。例如,在上述spider节点的最后一个crawl_rule节点中,不存在“to”属性,则根据该爬取规则所解析出的地址将被视为下载链接,并在经过去重之后添加到下载队列中,该规则与图7所示步骤相对应。而上述示例中的前四条具有“to”属性的爬取规则(crawl_rule)分别与图3~6所示的爬取规则相对应。
此外,在其他实施例中,也可以将另一特定类型的地址(页面)作为下载链接。例如,可以定义“download”类型的地址作为下载链接的类型,并在“to”属性中赋值“download”来表明根据该爬取规则解析出来的地址是应当被添加到下载队列中的下载地址。
此外,爬取规则(crawl_rule)节点中的xpath表达式可以通过两种方式指定:“xpath”属性和“restrict_xpath”属性。“restrict_xpath”属性提取的是html文件中的“a”标签,并将该“a”标签的“href”属性的值作为新地址。而“xpath”属性则直接提取地址字符串。由上述描述可知,“xpath”属性的功能强于“restrict_xpath”属性。但为了后向兼容性,需要提供“restrict_xpath”属性来兼容一些早期的网站。当两个属性同时存在时,本系统将忽略restrict_xpath属性。
crawl_rule节点的“filter_regex”属性指定了正则表达式。该正则表达式用于匹配根据“restrict_xpath”或“xpath”属性所提取出的地址字符串。若“filter_regex”属性存在,则程序会将根据“restrict_xpath”或“xpath”属性提取出的地址与相应正则表达式进行匹配。若匹配失败,则跳过该地址。若匹配成功,则将匹配出来的所有组(group)拼接起来作为最终的地址。例如,在提取出的地址字符串中出现的像“timestamp”这种参数在网页爬取时有可能会引发各种问题,因此针对例如以下网址:
www.domain.com/item?imestamp=6666&itemid=8888
可以使用类似于
(.*/item?)timestamp=\d*&(itemid=\d*)
之类的正则表达式来进行匹配。通过这种形式的正则匹配,将中间“timestamp”参数所在的那部分去除,仅留下前面的地址(字符串)以及需要的“itemid”参数(字符串)。并通过将这些字符串拼接起来得到最终的地址www.domain.com/item?itemid=8888。当然,字符串的数目不限于2个,在其他示例中,也可以是1个或3个以上。
当crawl_rule节点的“next_page”属性存在且为“true”时,意味着该规则为前述“翻页规则”。爬虫在爬取时通过记录已使用过这种规则的次数,可以识别当前爬取的链接在该网站的应用列表的第几页上。在本实施例中,在设计爬取规则时,要求仅在翻取“按更新时间排序”的列表时才定义该属性。在另一些实施例中,可以针对其他状态下的列表也定义该属性,即未必在“按更新时间排序”的状态下翻动列表。
当然,以上这些节点和/或属性的名称可以根据实现本发明的系统的需要而相应改变,并不限于以上示例所给出的形式。
此外,存在嵌入JS来生成页面链接的一些网站。而本系统的将xpath表达式与正则表达式相结合的爬取规则定义方式为处理此类网站提供了非常大的灵活性。参见图8和9,其示出了这种情况的一个较为简单的示例:“安智市场”的下载链接的提取。
如图8所示,“安智市场”的应用软件的下载链接并非实际的网络地址,而是一段JS代码,且下载地址嵌在该代码内部。在这种情况下,可以通过xpath表达式来选中相应html文件中的相应节点,然后用正则表达式匹配其中的下载链接。
例如,一条对应的爬取规则的示例如下:
<crawl_rulefrom=″topic″restrict_xpath=″//div[@class=′detail_down′]/a″filter_regex=″′(dl_app[^′]*)′″/>
其中,“from”属性表示本条爬取规则适用于“topic”属性的页面(即,信息页);没有“to”属性,表示根据本条爬取规则所解析出的地址是要被加入下载队列的下载链接;“restrict_xpath”属性表示从当前页面中提取出如上所述包含JS代码在内的相应html节点;以及“filter_regex”属性表示用于从该相应节点中提取相应下载地址的正则表达式,其中,在本示例中,该地址具有部分地址的形式。
实际上,利用xpath自带的字符串操作函数,我们能够处理一些更复杂的情况。例如,在软件下载网站“豌豆荚”的页面上并不存在直接的下载链接,而通过网络抓包工具“wireshark”侦听下载“豌豆荚”的apk类型软件时的数据包,可得知其下载链接具有以下形式:
http://apps.wandoujia.com/apps/包名/download
于是我们可以如图9所示根据以下爬取规则从网页中提取出包名并拼接出下载地址:
<crawl_rule from=″topic″xpath=″concat(′http://apps.wandoujia.com/apps/′,//a/@data-packagename,′download′)″/>
接下来,将详细描述在图1和2所示的示例分布式系统10中如何实现爬取规则。
在本实施例中,可以使用基于python的1xml库来解析具有xml格式的配置文件,并通过1xml自带的xpath相关功能提取出爬虫配置节点。当然,也可以使用基于其他语言的其他解析xml格式文件并处理xpath表达式的库来解析该配置文件,本发明不限于上述方法。
在本实施例中,定义了与前文所述的“spider”、“start_url”和“crawl_rule”配置节点分别对应的3个类SpiderConfig(针对爬虫的配置)、StartUrl(起始地址)、CrawlRule(爬取规则)。SpiderConfig类具有两个list对象,分别保存该节点内所有的StartUrl与CrawlRule配置。提取出的配置节点在内存中被转换为一个SpiderConfig类的实例供爬虫程序使用。
在控制器110解析起始地址之后,将起始地址写入爬取队列121_1~121_L中对应的爬取队列。在一个实施例中,可以按如下方式写入爬取队列:
1
angeeks
2
url=‘http://apk.angeeks.com/’,meta[‘type’]=‘home’,meta[‘depth’]=0,meta[‘page’]=0,meta[‘spider’]=‘angeeks’,meta[‘expire’]=3020
其中,“angeeks”表示该网站的简称,其用于在系统内部表示网站简称;“url”项的值表示该起始地址的URL,在本示例中为安极市场的URL;“type”项表示该URL指向的网页的类型,在本示例中为“home”;“depth”项表示该起始地址的初始爬取深度,在本示例中为“0”;“page”项表示该URL位于应用下载列表的第几页上,缺省为0,表示该起始地址不为翻页规则所针对的地址;“spider”项表示该起始地址所属的网站的简称,在本示例中为“angeeks”;以及“expire”项表示如果该起始地址被成功抓取,下一次最早重复抓取的时间,在本示例中,该最早重复抓取时间是在3020秒之后。
接下来,将详细描述在本发明的系统和方法中所使用的重爬机制。在通常情况下,会将已经爬取过的网址记录在去重列表中。而在新解析出的地址进入爬取队列(下载队列)前,都会将其与去重列表中的网址进行比较,并丢弃重复的地址以避免对网页的重复爬取。然而所有正常运转的软件下载网站都会对其提供下载的内容进行更新,而这些更新的内容通常会出现在应用下载列表的前几页上(例如,在按更新时间排序的情况下)。同时,这些最新更新的内容对于用户而言通常也较为重要。
但是由于去重列表的存在,现有的爬虫程序将会在判断出要爬取的地址是重爬列表中已经爬取过的地址时,自动放弃爬取该更新后的页面。为了应对这种页面(软件)更新的情况,我们需要一套新的重爬机制来保证应用列表的前几页(例如,在按更新时间排序的情况下)会以一定频率被重复爬取。
在本系统中,存在与重爬相关的两种机制,它们分别基于要爬取页面的类型和要爬取页面所在的页数。
(1)基于页面类型的重爬机制
对于不同类型的网页,为其分别定义去重列表中对应条目的有效期。在本示例中,由于详细信息页通常与要下载的软件包呈一一对应的关系,因此网页有效期的定义通常仅限于在解析出详细信息页(“topic”页)之前的网页。例如,在本示例中针对“home”、“list_”和“list”类型的页面定义有效期。在另一个实施例中,也可以为“topic”页设置有效期。在又一个实施例中,也可以不为其他类型页面设置有效期。针对页面的有效期的设置可以是根据具体需要来设置的。
该基于页面类型的重爬机制主要包括以下几点:
●使用Redis数据库的zset数据类型来存放去重列表。当爬虫完成对某个网址的爬取时,不仅需要将该网址记录在去重列表中,还需要将当前时间在具有zset数据类型的去重列表的对应z值中(以时间戳的形式)一并记录下来。
●将具体的有效期记录在爬取规则(crawl_rule)与起始地址(start_url)中。当通过某条爬取规则解析出或从起始地址列表中获取一个待爬取地址时,将该爬取规则或起始地址的有效期作为该地址的有效期。然后,将该地址的有效期与去重列表中对应的记录进行比对。若去重列表中无对应记录或对应记录已过期,则将该地址联同其有效期信息一同推入爬取队列。
●由于对于内容较为丰富的网站,解析出网址的时间与爬取该网址的时间可能相隔很久,因此为了避免由于相隔过久而导致有效期过期并重复爬取,在将网址从爬取队列中读出之后并在准备爬取之前,应当再次在去重列表中进行比较。“再次比较”主要是为了防止以下情况:由于解析地址和爬取地址之间相隔时间过久,导致去重列表中的有效期过期,而可能出现不想要的重复爬取。例如,在爬取队列中存在100个待爬取地址P1、P2、...、P100。在第一轮爬取中,顺序爬取P1、P2、...、P100所指向的网页,并对它们进行解析,得到了新的待爬取网页,例如P101。假定一轮的爬取并解析P1、P2、...、P100所耗费的时间是T1。当T1大于去重列表中的有效期时,由于P1、P2、...、P100在去重列表中对应项已过期,因此有可能不继续对P101进行爬取和解析,而是进行新一轮(第二轮)爬取并解析P1、P2、...、P100。假定这一轮的爬取并解析P1、P2、...、P100所耗费的时间是T2(由于例如系统负载的变化、网页内容的变化等导致T2与T1不同)。如果
P101的去重列表对应项的有效期<T2<P1~P100的去重列表对应项的有效期<T1此时,再一次解析出的P101同样将被添加到爬取队列中(因为其在去重列表中对应项的有效期已过,即T2大于其有效期)。此时,在爬取队列中存在两个相同的爬取地址P101,且很有可能它们的优先级是相同的。此外,由于T2小于P1~P100的去重列表对应项的有效期,则不会重复爬取P1~P100。此时,如果不在爬取之前在去重列表中对P101再次进行去重,则这两个相同的爬取地址很有可能在短时间内被重复爬取,造成目标网站的负载增高或者导致爬取失败。
如下表2所示,其描述了针对某一特定地址的多次爬取(下载)请求的可能处理情况(假定去重列表内的网页的有效期为3000秒):
表2
如上表所示,基于该网页的有效期,可以以不低于3000秒的间隔来重复爬取(下载)位于同一网络地址(下载地址)上的页面,从而可以获得更新后的页面。
如本领域技术人员将注意到的:有效期属性实际上依附于起始规则(start_url)与爬取规则(crawl_rule)。由于对于大部分网站,同样类型的网页重爬间隔可以相同。因此在本实施例中,为了简化有效期的定义,通常通过类型来指定页面有效期(expire属性),如以下示例所示:
(在未使用priority属性的情况下,expire=”0”即意味着不会过期)
因此,可通过例如以下方式为针对特定网站的爬取规则或起始地址定义有效期:
如上面的示例所示,针对“安极市场”的起始地址,定义其在去重列表中的页面有效期为5000秒,而针对例如在“游戏”主列表页中解析出的“按更新时间排序”的页面,定义其在去重列表中的页面有效期为4000秒。即,针对起始地址,每隔最少5000秒才可能重新抓取一次,而对于“按更新时间排序”的第一个列表页,每隔最少4000秒才可能重新抓取一次。
此外,在本实施例中,对于未定义“expire”属性的爬取规则,其有效期与“to”属性所指定的网页类型的有效期相同。而对于未定义“expire”属性的起始地址,其有效期与起始地址类型(默认为“home”)的有效期相同。当然,对于未定义“expire”属性的爬取规则和起始地址,也可以定义其它的有效期。例如,可以为未定义“expire”属性的爬取规则和起始地址指定固定的缺省有效期等等。
(2)基于页数的重爬机制
在一些情况下,较为活跃的软件下载站在更新应用时有时会将已下架软件的详细信息页地址重新用于其它软件,或者用于该软件的更新版本,因此同一信息页地址可能对应于不同的软件或相同软件的不同版本。这就意味着要对于详细信息页地址定义有效期,以便能够获取更新的软件。然而对于大部分网站,都不会为详细信息页面定义有效期。在本实施例中,采用以下方式处理这种情况。
对于需要翻页才能遍历应用下载列表的网站,在解析其待下载网址的时候可以通过以上爬取规则的“next_page”属性以及对相应规则的使用次数来知道当前的页数。考虑到更新的应用一般会出现在列表的前几页,因此只要对从前几页的列表页中解析出的详细信息页采用一个较大的有效期,即可处理上述情况。由于该有效期的值通常很大,大部分页面在经过这段时间后通常会被挤出前几页。对于极小部分未被挤出前几页的链接,由于间隔很长,因此其重爬开销也可以基本被忽略。
在一个示例中,可以将从页数小于5的列表页(“list”)中解析出的无有效期的详细信息页(“topic”)的有效期置为1000000秒(11.57天)。从而,对于大部分应用下载网站而言,基本不存在相隔11天以上还保持在前5页中的下载地址。
这样,通过上述两种重爬机制,即“基于页面类型的重爬机制”和“基于页数的重爬机制”,可以在使得去重过滤器支持有效期的同时,也能针对不同页面类型和不同页数来分别设置有效期。
接下来,将结合图10和图11来详细描述根据本发明的实施例的爬取/下载流程。图10所示的爬取流程和图11所示的下载流程可以由本系统中的爬虫和下载器分别执行。此外,在其他实施例中,图10所示的爬取流程和图11所示的下载流程也可以由同一节点来执行,即该节点同时具备爬虫和下载器的功能。
首先从总体上描述本系统的爬取/下载流程的主要特点:
●通过Redis数据库将爬取/下载过程中所用到的各队列/列表公有化,使得控制器、一个或多个爬虫、以及一个或多个下载器能够访问同一套配置并实现分布式爬取。
●对于要下载的每一个网站,Redis数据库中均具有对应的一组队列/列表(zset实现)。该组队列/列表包括例如:起始地址列表、爬取队列、下载队列、爬取去重列表、解析去重列表、下载去重列表、以及文件去重列表,其中,爬取队列与下载队列采用优先级作为zset数据类型中的z值,而其余列表均采用时间戳作为z值。
●将爬取/下载过程分离,从而允许对两个流程采用不同的方式进行调度控制/性能优化等。
●根据所在页数,对下载链接的优先级进行初始化。此外,对于准备下载的下载链接,采用指数形式的方式更新其优先级并立刻置回下载队列。该机制可以使页数靠前(较新)的软件会被以较高的优先级下载。使得从下载失败到后续的重新加载之间存在一定的间隔,增加了成功重新下载的概率,并保证了下载地址在下载开始前即被置回下载队列,而不会在下载过程中因其他原因丢失(对于下载成功的情况,该地址再次被读取时会被去重列表过滤掉)。
接下来,结合图10所示的方法200来详细描述爬取流程。方法200开始于步骤S210,在步骤S210,控制器110(或任意其他节点,例如爬虫130_1~130_N或下载器140_1~140_M)从针对要下载的网站的配置文件中读出对应spider节点中的所有起始地址(start_url),并将其存入数据库120中的起始地址列表127_1。在本示例中,要下载的网站数目为1(L=1)。当然在其他实施例中,可以存在多个要下载的网站。在该情况下,可以在针对不同网站的起始地址列表中存入相应的一个或多个起始地址。
在步骤S220,各个爬虫模块130_1~130_N(或任意其他节点,例如控制器110)以固定或可变时间间隔来读取起始地址列表127_1中的地址,并将其存入爬取队列121_1(由于在本示例中L=1,因此仅存在一个爬取队列121_1;此外,为了描述的简单,不对要下载的网站分组或仅将它们分为1组)。将起始地址列表127_1中的地址存入爬取队列121_1的具体方式可以取决于实现方式而不同。例如,可以由预先指定的单一爬虫(例如,130_1)将起始地址列表127_1中的地址存入爬取队列121_1;也可以由预先指定的多个爬虫(例如,130_1和130_2)将起始地址列表127_1中的地址存入爬取队列121_1,其中,每个爬虫负责一半的地址;以及也可以由多个爬虫130_1~130_N根据其它预先指定或实时生成的标准将起始地址列表127_1中的地址存入爬取队列121_1。本发明不限于上述任一种存入方式。
此外,在本示例中,采用类似重爬机制的方式来控制读取间隔(例如,读取时在起始地址列表127_1内记录时间戳)。当然,也可以使用其他方式来控制读取间隔。
在步骤S230,各个爬虫模块130_1~130_N从爬取队列121_1中读取记录,读取时的优先级为负的爬取深度,即爬取深度越深的网址优先级越低。因此,爬虫模块130_1~130_N将优先处理爬取深度较浅的网址。当然,优先级的设置完全取决于系统实现的需要,即可以根据不同的需求将优先级设置为不同的数值。在另一个实施例中,可以优先处理爬取深度较深的网址。
在步骤S240,爬虫模块130_1~130_N使用爬虫去重列表123_1对读取的记录去重。即,如果发现重复爬取,则直接丢弃该待爬取地址,且方法200返回步骤S230处理爬取队列121_1中的后续记录。否则,继续执行步骤S250。
在步骤S250,爬虫模块130_1~130_N从互联网下载该地址所指向的页面,若下载失败则丢弃该待爬取地址,并返回步骤S230处理爬取队列121_1中的后续记录。否则,继续执行步骤S260。
在步骤S260,爬虫模块130_1~130_N使用当前爬取地址(成功下载了与该爬取地址相对应的页面)来更新爬虫去重列表123_1,并将该地址对应的页面送入解析器解析。该解析器可以是各个爬虫模块130_1~130_N中各自拥有的解析器,也可以是控制器110或其他节点中的单一解析器。此外,该解析器也可以是在分布式系统10之外的第三方解析器。
在步骤S270,判断解析器解析出来的需要继续爬取的地址指向网页还是应用程序,当确定指向网页时,执行步骤S280,否则执行步骤S290。
在步骤S280,经爬虫去重列表123_1去重后将需要继续爬取的地址重新存入爬取队列121_1,并返回步骤S230。
在步骤S290,对于解析器解析出来的应用程序的下载地址,使用解析去重列表124_1去重。如果发现重复解析,则直接丢弃该地址,且方法200返回步骤S230处理爬取队列121_1中的后续记录。否则,继续执行步骤S295。
在步骤S295,使用该地址来更新解析去重列表124_1,并将该地址存入下载队列122_1。在存入下载队列122_1时相应项的优先级可以是:对于存在页数信息的页面(即,使用翻页规则的页面解析),优先级为负的页数-100。对于不存在页数信息的页面(即,不使用翻页规则的页面解析),优先级为负的爬取深度-200。当然,优先级的设置完全取决于系统实现的需要,即可以根据不同的需求将优先级设置为不同的数值。在另一个实施例中,可以优先处理页数较大的网址或爬取深度较深的网址。
在步骤S297,判断爬取队列121_1是否为空,如果为空,则方法200结束,否则方法返回步骤S230。此外,方法200的结束条件不限于此,也可以根据是否到达预定爬取深度或者这二者的组合来判断方法200是否结束。
通过图10所示的爬取流程,可以用分布式的方式将指定网站的网页中包含的下载链接提取到下载队列122_1中,与后续下载流程的处理完全分离且互不影响,从而方便了针对页面爬取和应用下载进行不同的优化/配置/处理。
接下来,结合图11所示的方法300来详细描述下载流程。方法300开始于步骤S310,在步骤S310,下载模块140_1~140_M根据在方法200的步骤S295中设置的优先级,从下载队列122_1中读取待下载地址。
在步骤S320,使用下载去重列表125_1对读取的待下载地址进行去重。即,如果发现重复下载,则直接丢弃该待下载地址,且方法300返回步骤S310以处理下载队列122_1中的后续记录。否则,继续执行步骤S330。
在步骤S330,将该下载地址的优先级×2。若优先级大于-10000,则置回下载队列122_1,否则认为该地址无法重新下载,丢弃。该步骤S330的主要作用是判断是否对该地址进行了太多次的下载尝试。当由于该下载地址尝试次数过多,而导致优先级低于-10000时,则应当判定该地址无效并丢弃该地址。在该情况下,方法300返回步骤S310以处理后续记录。否则,继续执行步骤S340。此外,优先级阈值并不一定是-10000,也可以是满足系统需求的其他预定值。
在步骤S340,下载模块140_1~140_M通过互联网下载该地址指向的文件。若下载失败则跳过该待下载地址,并返回步骤S310处理下载队列122_1中的后续记录。否则,继续执行步骤S350。
在步骤S350,在下载文件成功的情况下,使用该下载地址来更新下载去重列表125_1。
在步骤S360,对已下载的文件进行各种检查,例如:其是否为目标类型的文件,文件是否损坏等。
在步骤S370,针对已下载的文件计算数字摘要(例如,md5、sha1等),并使用该数字摘要来检查文件去重列表126_1。当发现文件去重列表126_1中存在与计算出的数字摘要匹配的项,即意味着该文件已在其他网址处被下载过,且因此可以丢弃该文件,并直接返回步骤S310。否则,继续执行步骤S380。
在步骤S380,使用已下载的文件来更新文件去重列表126_1,并将其存入文件系统。具体地,可以使用该文件的数字摘要或其它可以用于将该文件与其他文件相区别的标识符或特征来更新文件去重列表126_1。
在步骤S390,判断下载队列122_1是否为空,如果为空,则方法300结束,否则方法返回步骤S310。
从而,通过图11所示的下载方法,可以实现针对特定类型数据(在本示例中,应用程序)的分布式下载,同时可以通过各个去重列表以及如上所述的相关有效期来控制去重过程和重复下载过程。
接下来将描述本系统在不采用单独搭建的日志系统的情况下如何提供与爬取/下载相关的日志数据以及提供的日志数据的内容。
如上所述,本系统中的所有队列/列表/配置等均保存在公共的(Redis)数据库120中。而本系统的各个模块(控制器110、爬虫130_1~130_N、下载器140_1~140_M)均通过数据库120进行交互。通过统计数据库120内各列表/队列的状态,即可整体上大致掌握本系统的状态。
例如,由于各个列表附带时间戳(例如,z值),通过计算各去重列表落在特定时间段内的记录数量,可获得该时间段内的爬取/下载情况。
在一个实施例中,示例统计方式如下所示(以安极市场在时间段2013/03/12~2013/03/13期间的爬取/下载数据为例):
当前爬取队列长度=1
爬虫去重列表总长度=65344
解析去重列表总长度=60445
下载去重列表总长度=60444
文件去重列表总长度=60286
指定时间段内爬虫去重列表长度=831
指定时间段内解析去重列表长度=16
指定时间段内下载去重列表长度=16
指定时间段内文件去重列表长度=16
从而,可以间接获得的系统统计数据至少包括以下各项:
待爬取地址的数量=当前爬取队列长度=1
待下载地址的数量+被丢弃的下载地址数量=解析去重列表总长度-下载去重列表总长度=1
已爬取的页面总数=爬虫去重列表总长度=65344
解析出的总下载链接数=解析去重列表总长度=60445
已成功下载的下载链接总数=下载去重列表总长度=60445
成功爬取的文件总数=文件去重列表总长度=60286
指定时间段内解析出的下载链接数=指定时间段内解析去重列表长度=16
指定时间段内成功下载的下载链接=指定时间段内下载去重列表长度=16
指定时间段内成功爬取的文件总数=指定时间段内文件去重列表长度=16
此外,当指定时间段的结束时间为当前时间时:
指定时间段内爬虫爬取的页面数量=指定时间段内爬虫去重列表长度=831
因此,如上所述,可以通过数据库120中保存的各个队列/列表的统计信息,来获得本系统的爬取/下载相关统计信息。从而避免了搭建单独的日志系统。
接下来,将详细描述爬取/下载组的实现和使用。如前所述,在本实施例中,爬虫采用了基于scrapy的爬虫框架,而基于scrapy的爬虫框架的问题在于:每个进程需要消耗200~300MB的内存。在该情况下,当要爬取的网站总数较多时,为每个网站启动一个进程的资源消耗也会变得相当巨大。
因此,在图10和11所示实施例中,不对要下载的网站进行分组或仅分为一组,以使得针对多个网站可以使用同一组爬虫/下载器,从而能够节约资源。然而在本发明的另一些实施例中,也可以将要下载的网站分为多个组,并通过使用针对各个组的不同配置,来实现爬虫/下载模块的组控制。
具体地,在控制器110启动爬虫/下载器时,可以指定该爬虫/下载器所对应的爬取/下载组的组名,在未指定的情况下,可以将组名置为空(或其他缺省组名)。此外,可以设置定时时间为2s的定时器(例如,twisted.internet.task.LoopingCall),每次定时器被触发都会触发调度器中的以下流程(例如,next_request):
1、基于爬取/下载组名与预设的SPIDER_CYCLE_KEY,拼接出数据库120中爬取循环的键名(数据结构为zset类型)。从该zset中获取时间戳(z值)最小且小于“当前时间”的一条记录,该记录内容为网站名称。若无符合要求的记录则停止(例如,返回none)。若成功获取该记录则将该记录的时间戳更新为“当前时间”+“下载延迟”;
2、通过针对该网站的爬取队列的键名,从该爬取队列中读取一条待爬取的地址。在一个实施例中,该地址为scrapy中Request对象的实例。Request对象可通过scrapy自带的request_to_dict方法转成dict后再序列化,然后存入数据库120中。该实例的meta属性中附带类型(“type”)、爬取深度(“depth”)、当前页数(“page”)、所属网站(“spider”)等信息;
3、返回该Request对象后,scrapy框架将自动重新进入next_request流程,即回到1继续获得下一个需要爬取的网站;
4、获取该爬虫的SpiderConfig配置对象,若此时为该爬虫程序(模块)第一次爬取该网站,则从数据库120内读取该网站配置的对应节点(xml字符串),并将其解析为SpiderConfig对象;
5、下载该地址指向的页面。若下载失败,该地址将以较低的优先级置回爬取队列重新调度,具体的调度方式参照方法200和300中关于优先级的相应步骤;
6、使用1xml库来解析该html页面的“body”部分;
7、获取一条尚未应用过的爬取规则,其“from”属性等于当前爬取页面的类型;
8、根据爬取规则来解析出后续地址,并生成地址列表:
a)若该爬取规则定义了“xpath”属性,使用该属性的值在由1xml解析出的对象中进行提取,判断解析结果类型,并将其统一转换为子项为字符串的list对象;在一个实施例中,对于不正确的类型(节点等)可以直接丢弃;此外,可以将此list对象作为地址列表返回;
b)若该爬取规则定义了“restrict_xpath”属性,使用该属性的值在由1xml解析出的对象中进行提取,判断解析结果类型,并将其统一转换为子项为html标签的list对象;对于不正确的类型(字符串等)可以直接丢弃;然后,对列表对象中的每个标签,可以提取其“href”属性,生成一个新的字符串list;对于无href属性的“a”标签可以直接丢弃;此外,可以将此list对象作为地址列表返回;
c)若该爬取规则未定义“xpath”属性及“restrict_xpath”属性,则可以用xpath=‘//a/@href’的方式进行处理;
9、若该爬取规则定义了“filter_regex”属性,使用该属性中的正则表达式对地址列表中的每一项进行匹配并按以下规则更新地址列表:
a)若匹配结果为空,则可以删除该项;
b)可以将匹配结果中的各字符串拼接起来,作为新的地址,替代原列表中对应的字符串;
10、可以使用“urlparse”库内的“urljoin”将地址列表内的相对(部分)URL转换为绝对(完全)URL。
当然,上述定时时间为2s的定时器并不是必需的。也可以使用具有其它定时时间的定时器,例如1s、10s等等,只要其满足用户对爬取网站频率的要求即可。此外,该定时器可以是可变的,即针对不同的循环采取不同的定时时间。
在一个实施例中,可以通过控制器110来设定多个不同的爬取/下载组。针对每个组,在数据库120中均维护一个相应的网站列表。每个爬虫/下载模块启动时,均可指定一个组名(不指定时采用默认的组名)。模块启动后即如上所述按照针对其所属的组所维护的列表进行爬取。
每个爬取/下载组采用zset数据结构保存在数据库120中,其键名可以基于组名拼接而成(例如,“crawl_”+“组1”)。该爬取/下载组的各成员可以为网站名称(例如angeeks),成员的z值可以为允许下次爬取的时间。
在爬虫/下载模块访问数据库时,仅获取z值小于当前时间的记录(成员)的集合作为接下来需要爬取的网站列表。对于爬虫模块,可以直接使用“当前时间”+“爬取间隔”作为允许下次爬取的时间,来更新各网站(表中各成员)对应的z值。对于下载模块,可以在获得网站列表的同时使用“当前时间”+“下载超时时间”+“下载间隔”来更新对应的z值,下载结束后还需要再使用“当前时间”+“下载间隔”对网站的对应z值进行重新更新。
由于一般而言,网站对爬取间隔并不敏感,因此本系统中优选地将爬取间隔统一设置为2s,将下载间隔的默认值设为10s。当然,爬取间隔和下载间隔的默认值不限于2s和10s,其他任何满足用户需要的值也是可能的。此外,可以通过以下方式在针对各个网站的配置节点中分别设定不同的下载间隔,例如:
<spidername=″tgbus″channel=″1143″download_delay=″1000″>
根据如上设置的配置,爬虫以缺省爬取间隔(2s)来获取网站列表,且除了网站“tgbus”之外,针对其他网站都使用缺省下载间隔10s,而对于“tgbus”则使用其特定的下载间隔1000s。此外,当下载一个应用软件(软件包)完成后,下载器即获取一次网站列表,同时也以固定间隔(60s)来获取网站列表,以避免卡死。
为了能够动态改变各个组的成员,控制针对特定网站的爬虫的启动/停止状态,可以采用下述方法。各个爬虫/下载器均通过访问数据库120中对应的爬取/下载组来获取需要爬取/下载的网站名称。通过专门的控制器110向各个组中插入/移除成员,即可达到对网站状态启动/停止的控制目的。即,当想要启动针对特定网站的爬取/下载时,可以通过向数据库120中相应组的爬取/下载列表添加针对该特定网站的起始地址(“home”)来实现;以及当想要停止针对特定网站的爬取/下载时,可以通过从数据库120中相应组的爬取/下载列表中移除指向想要停止的特定网站的所有现有地址来实现。此外,通过针对列表中的指定成员(记录/地址)设定特定的z值,还可以使得爬虫/下载器延迟启动,从而实现更灵活的爬虫/下载器调度。
表3中给出了爬取/下载组中针对不同下载模块的示例调度流程,其中,下载超时时间2000s,tgbus的下载延迟1000s,其余各站10s:
表3
如表3所示,该下载器组中包括两个下载模块(下载模块1和下载模块2),该下载器组的下载队列中包括至少四个目标网站,分别以angeeks、anzhi、baidu和tgbus表示。在初始时间1363000000处,下载模块1启动,并从下载队列中获取这四个网站的地址作为初始下载地址,并分别更新该下载器组的访问限制列表(例如,访问限制列表128_1)中对应网站的下次下载时间(延迟时间),此时由于下载尚未完成,因此将“当前时间”+“下载超时时间2000s”+“下载延迟10s”作为下次下载时间来进行更新。
在下载模块1成功下载angeeks和anzhi的应用软件之后,由于已经成功下载,如表3中第2、3项分别所示,将当前时间+“下载延迟10s”作为下次下载时间来进行更新。
在时间1363000040处,下载模块2启动,并从下载队列中获取angeeks的地址作为初始下载地址,并分别更新该下载器组的访问限制列表中对应网站的下次下载时间(延迟时间),此时由于下载尚未完成,因此将“当前时间”+“下载超时时间2000s”+“下载延迟10s”作为下次下载时间来进行更新。
之后,根据上述类似的更新方式,分别更新baidu、tgbus等的下次下载时间,从而实现如上所述的组内调度方式。
接下来,将详细描述控制器(控制模块)110的实现和使用。如前文所述,针对不同网站部署爬虫通常是一件非常繁重/容易出错的工作。为此,根据本发明的实施例的分布式系统10的调度管理均基于数据库120。在分布式系统10中,通过不同的队列/列表等来管理不同的功能,因此各模块之间的关系是松耦合,且因此能够形成非常灵活的拓扑结构。可以简单地通过添加/修改/删除数据库120中的各个列表/队列中的成员来控制整个分布式系统10的各个模块。
因此,基于本系统的这些特点,需要一种功能全面的控制模块,并将整个网站部署与调整流程本地化,以简化爬虫的维护工作。
具体地,在一个实施例中,分布式系统10的控制模块110提供以下功能:
(1)更新配置,通过以前文所述方式来添加/修改/删除针对各个网页类型的有效期的配置和/或针对各个网站的配置;
(2)查看网站列表,查看所有已配置的网站的相关信息;
(3)查询统计信息,如前文所述查看分布式系统10的统计信息,并通过输入起始时间与终止时间来指定欲查看的指定时间段。此外,也可以通过输入起始时间和时间段长度,或通过输入终止时间和时间段长度来指定欲查看的指定时间段;
(4)重置网站,重置针对特定网站的所有列表与队列中的成员(例如,将队列/列表中的成员(包括其地址、有效期等)返回初始状态),重置后即可重新开始爬取该网站;
(5)清除网站,清除针对特定网站的所有列表与队列中的成员(例如,将队列/列表中的成员(包括其地址、有效期等)从队列/列表中移除),并清除网站相关配置;
(6)查看地址,查看特定网站中特定地址的状态,通过查看该地址是否在各去重过滤器中出现,可检测该地址的爬取状态(包括未出现、待爬取、已爬取、待下载、已下载);
(7)切换当前爬取/下载组,当控制模块110启动时,控制模块110所在组为默认组(例如,组名可以为空),通过该命令切换控制模块110进行控制所针对的爬取/下载组;
(8)开始网站爬取/下载,该功能包含3种命令,分别是:启动爬取(例如,通过向相应爬取组的起始地址列表添加新的要爬取的起始地址)、启动下载(例如,通过向相应下载组的下载队列添加新的要下载的地址)、以及同时启动这两者;
(9)停止网站爬取/下载,该功能包含3种命令,分别是:停止爬取(例如,通过从相应爬取组的起始地址列表和爬取队列中移除所有项)、停止下载(例如,通过从相应下载器组的下载队列中移除所有项)、以及同时停止这两者。
此外,如前文所述,根据本发明的实施例的分布式系统10在设计时即要求爬取大量网站,且在实际使用过程中常常会需要实时增加要下载的网站。可通过下面的流程在本地(例如,在控制器110处,当然也可以通过与数据库120相连并可以对数据库120中维护的队列/列表/配置等进行操作的其他节点)部署要下载的新网站:
(1)根据网站结构,如前文所述设置一条或多条爬取规则;
(2)在测试专用组(爬取/下载组)内启动针对该该网站的爬取与下载;
(3)根据该测试专用组的针对该网站的爬取规则,通过本地执行的爬虫/下载器来测试爬取该网站;
(4)检查爬取过程(包括,查看统计数据、查看爬取下来的网页、软件包等),若存在异常,可在本地直接进行调试(包括,修改针对该网站的爬取规则等),确认问题并对爬取规则/各个爬取参数(例如,时间间隔/延迟量)等进行相应调整;
(5)在确认爬取过程正常后,重置该网站的状态,停止在测试组内对该网站的爬取与下载;以及
(6)在目标组内正式启动爬虫/下载器,以根据调整后的配置(爬取规则)等对该网站进行正式爬取/下载。
此外,如前文所提及的,已配置好的网站有时也可能会进行改版(例如,网页上相应链接变更了具体的名称/地址等),改版通常导致原来配置好的爬取规则无法正常工作,需要重新进行配置。因此,需要检查分布式系统10的工作状态,对发生改版的网站(例如,通过检查统计信息发现针对某个网站的爬取失败次数过多)调整网站配置的工作可通过以下流程在本地完成:
(1)查询指定时间段内(例如,当周、当月、当季度等)整个系统的统计信息,检查各解析出下载链接数小于等于特定阈值(例如,0)的各网站是否发生了改版;
(2)在针对该网站的相应爬取/下载组内停止针对发生了改版的网站的爬取/下载;
(3)调整针对该网站的爬取规则;
(4)在测试专用组(爬取/下载组)内启动针对该该网站的爬取与下载;
(5)根据该测试专用组的针对该网站的爬取规则,通过本地执行的爬虫/下载器来测试爬取该网站;
(6)检查爬取过程(包括,查看统计数据、查看爬取下来的网页、软件包等),若存在异常,可在本地直接进行调试(包括,修改针对该网站的爬取规则等),确认问题并对爬取规则/各个爬取参数(例如,时间间隔/延迟量)等进行相应调整;
(7)在确认爬取过程正常后,重置该网站的状态,停止在测试组内对该网站的爬取与下载;以及
(8)在相应组内重新启动爬虫/下载器,以根据调整后的配置(爬取规则)等对该网站进行再次爬取/下载。
至此已经结合优选实施例对本发明的一些方面进行了描述。应该理解,本领域技术人员在不脱离本发明的精神和范围的情况下,可以进行各种其它的改变、替换和添加。因此,本发明的范围不局限于上述特定实施例,而应由所附权利要求所限定。
Claims (28)
1.一种用于下载网站数据的分布式方法,包括以下步骤:
设定一个或多个下载组,
在数据库中针对每个下载组维护相应的网站列表;
一个或多个下载模块中的每个下载模块根据针对与其相关联的下载组所维护的网站列表来获取相应网站的一个或多个下载队列;以及
所述每个下载模块根据所述一个或多个下载队列来进行下载,
其中,所述网站列表中的记录均具有下次下载时间项,以及下载模块根据针对与其相关联的下载组所维护的网站列表来获取相应网站的一个或多个下载队列的步骤还包括:
所述下载模块仅获取下次下载时间项的值小于当前时间的记录来获取相应网站的一个或多个下载队列。
2.根据权利要求1所述的方法,其中,通过在启动所述下载模块时指定组名,将所述下载模块和与所述组名相关联的下载组相关联。
3.根据权利要求1所述的方法,其中,当在启动所述下载模块时未指定组名时,将所述下载模块与缺省下载组相关联。
4.根据权利要求1所述的方法,其中,所述一个或多个下载模块至少包括第一下载模块和第二下载模块,以及在获得网站列表的同时如下更新所述下次下载时间项的值:
针对所述第一下载模块,所述下次下载时间项的值等于当前时间与爬取间隔之和;以及
针对所述第二下载模块,所述下次下载时间项的值等于当前时间、下载超时时间、以及下载间隔之和。
5.根据权利要求4所述的方法,其中,所述爬取间隔是2秒。
6.根据权利要求4所述的方法,其中,所述下载间隔是10秒。
7.根据权利要求4所述的方法,其中,针对所述第二下载模块,在完成下载之后,使用当前时间与下载间隔之和再次更新所述下次下载时间项。
8.根据权利要求4所述的方法,其中,所述第一下载模块以固定时间间隔来获取网站列表。
9.根据权利要求4所述的方法,其中,所述第二下载模块在预定事件发生时获取网站列表,同时也以固定时间间隔来获取网站列表。
10.根据权利要求1所述的方法,其中,通过向网站列表中插入/移除记录来控制针对相应网站的下载的启动/停止。
11.根据权利要求1所述的方法,还包括:
根据网站的结构设置爬取规则;
根据所述爬取规则,使用与测试专用组相关联的下载模块来尝试下载所述网站的数据;
检查下载到的数据,确认是否存在异常,如果存在异常,则在本地调试所述爬取规则并解决导致异常出现的问题;
在确认数据正常之后,清除所述测试专用组;以及
在目标组中正式启动相应下载模块来下载所述网站的数据。
12.根据权利要求1所述的方法,还包括:
查询统计信息,检查是否存在网站数据的下载异常;
如果存在异常,则停止发生异常的下载;
根据针对下载异常的网站的爬取规则,使用与测试专用组相关联的下载模块来尝试下载所述网站的数据;
检查下载到的数据,确认是否存在异常,如果存在异常,则在本地调试所述爬取规则并解决导致异常出现的问题;
在确认数据正常之后,清除所述测试专用组;以及
正式启动和与下载异常的网站相对应的下载组相关联的下载模块来重新下载所述网站的数据。
13.根据权利要求1所述的方法,其中,所述当前时间以所述数据库中的时间为准。
14.根据权利要求1所述的方法,还包括:
如果针对下载队列中的地址下载失败,则将所述地址以较低优先级置回所述下载队列中,以便重新调度下载。
15.一种用于下载网站数据的分布式系统,包括:
控制器,用于设定一个或多个下载组,
数据库,用于针对每个下载组来维护相应的网站列表;以及
一个或多个下载模块,每个下载模块用于根据针对与其相关联的下载组所维护的网站列表来获取相应网站的一个或多个下载队列,以及根据所述一个或多个下载队列来进行下载,
其中,所述网站列表中的记录均具有下次下载时间项,以及所述下载模块还被配置为:
仅获取下次下载时间项的值小于当前时间的记录来获取相应网站的一个或多个下载队列。
16.根据权利要求15所述的系统,其中,通过在启动所述下载模块时指定组名,将所述下载模块和与所述组名相关联的下载组相关联。
17.根据权利要求15所述的系统,其中,当在启动所述下载模块时未指定组名时,将所述下载模块与缺省下载组相关联。
18.根据权利要求15所述的系统,其中,所述一个或多个下载模块至少包括第一下载模块和第二下载模块,以及在获得网站列表的同时如下更新所述下次下载时间项的值:
针对所述第一下载模块,所述下次下载时间项的值等于当前时间与爬取间隔之和;以及
针对所述第二下载模块,所述下次下载时间项的值等于当前时间、下载超时时间、以及下载间隔之和。
19.根据权利要求18所述的系统,其中,所述爬取间隔是2秒。
20.根据权利要求18所述的系统,其中,所述下载间隔是10秒。
21.根据权利要求18所述的系统,其中,针对所述第二下载模块,在完成下载之后,使用当前时间与下载间隔之和再次更新所述下次下载时间项。
22.根据权利要求18所述的系统,其中,所述第一下载模块以固定时间间隔来获取网站列表。
23.根据权利要求18所述的系统,其中,所述第二下载模块在预定事件发生时获取网站列表,同时也以固定时间间隔来获取网站列表。
24.根据权利要求15所述的系统,其中,所述控制器通过向网站列表中插入/移除记录来控制针对相应网站的下载的启动/停止。
25.根据权利要求15所述的系统,其中,通过以下方式来部署针对网站的爬取规则:
根据网站的结构设置爬取规则;
根据所述爬取规则,使用与测试专用组相关联的下载模块来尝试下载所述网站的数据;
检查下载到的数据,确认是否存在异常,如果存在异常,则在本地调试所述爬取规则并解决导致异常出现的问题;
在确认数据正常之后,清除所述测试专用组;以及
在目标组中正式启动相应下载模块来下载所述网站的数据。
26.根据权利要求15所述的系统,其中,通过以下方式来调整针对网站的爬取规则:
查询统计信息,检查是否存在网站数据的下载异常;
如果存在异常,则停止发生异常的下载;
根据针对下载异常的网站的爬取规则,使用与测试专用组相关联的下载模块来尝试下载所述网站的数据;
检查下载到的数据,确认是否存在异常,如果存在异常,则在本地调试所述爬取规则并解决导致异常出现的问题;
在确认数据正常之后,清除所述测试专用组;以及
正式启动和与下载异常的网站相对应的下载组相关联的下载模块来重新下载所述网站的数据。
27.根据权利要求15所述的系统,其中,所述当前时间以所述数据库中的时间为准。
28.根据权利要求15所述的系统,其中,所述下载模块还被配置为:
如果针对下载队列中的地址下载失败,则将所述地址以较低优先级置回所述下载队列中,以便重新调度下载。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201310198673.8A CN103475687B (zh) | 2013-05-24 | 2013-05-24 | 用于下载网站数据的分布式方法和系统 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201310198673.8A CN103475687B (zh) | 2013-05-24 | 2013-05-24 | 用于下载网站数据的分布式方法和系统 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN103475687A CN103475687A (zh) | 2013-12-25 |
CN103475687B true CN103475687B (zh) | 2016-12-28 |
Family
ID=49800381
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201310198673.8A Expired - Fee Related CN103475687B (zh) | 2013-05-24 | 2013-05-24 | 用于下载网站数据的分布式方法和系统 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN103475687B (zh) |
Families Citing this family (23)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN104657399B (zh) * | 2014-01-03 | 2017-11-07 | 广西科技大学 | 网络爬虫控制方法 |
CN103873597B (zh) * | 2014-04-15 | 2017-10-10 | 厦门市美亚柏科信息股份有限公司 | 分布式网页下载方法和系统 |
CN104077422B (zh) * | 2014-07-22 | 2018-05-01 | 百度在线网络技术(北京)有限公司 | 下载apk的去重方法及装置 |
CN104166729A (zh) * | 2014-08-28 | 2014-11-26 | 四川长虹电器股份有限公司 | 定时多任务网页数据抓取系统及方法 |
CN104219312B (zh) * | 2014-09-05 | 2017-08-08 | 无锡天脉聚源传媒科技有限公司 | 一种安装程序的方法及装置 |
CN104778277A (zh) * | 2015-04-30 | 2015-07-15 | 福州大学 | 一种基于Redis的RDF数据分布式存储和查询方法 |
CN105183858B (zh) * | 2015-09-10 | 2018-12-21 | 国家计算机网络与信息安全管理中心 | 一种基于消息队列的分布式数据实时去重方法 |
CN105721631B (zh) * | 2016-03-28 | 2019-04-30 | 中国科学院信息工程研究所 | 一种定向信息抓取场景中大规模ip地址资源使用方法 |
CN106384292A (zh) * | 2016-09-14 | 2017-02-08 | 哈尔滨工业大学(威海) | 社交网络用户关系采集系统及方法 |
CN108228151A (zh) * | 2016-12-22 | 2018-06-29 | 北京询达数据科技有限公司 | 一种新型网络机器人的设计方法 |
CN108874513A (zh) * | 2017-05-11 | 2018-11-23 | 北京京东尚科信息技术有限公司 | 处理定时任务的方法、系统、电子设备和计算机可读介质 |
CN110120965A (zh) * | 2018-02-07 | 2019-08-13 | 北京世纪好未来教育科技有限公司 | 课件的下载方法、教学系统及存储介质 |
CN108989304A (zh) * | 2018-07-05 | 2018-12-11 | 北京广成同泰科技有限公司 | 一种可信软件白名单构建方法 |
CN109165333A (zh) * | 2018-07-12 | 2019-01-08 | 电子科技大学 | 一种基于网页数据的高速主题爬虫方法 |
CN109614535B (zh) * | 2018-11-29 | 2021-10-08 | 中电万维信息技术有限责任公司 | 一种基于Scrapy框架的网络数据的采集方法及装置 |
CN109710831A (zh) * | 2018-12-28 | 2019-05-03 | 四川新网银行股份有限公司 | 一种基于浏览器插件的网络爬虫系统 |
CN109829095A (zh) * | 2019-02-12 | 2019-05-31 | 苏州思必驰信息科技有限公司 | 网页信息的获取方法及系统 |
CN110597764B (zh) * | 2019-10-10 | 2024-05-07 | 深圳前海微众银行股份有限公司 | 一种文件下载、版本管理方法及装置 |
CN111262797A (zh) * | 2020-01-09 | 2020-06-09 | 深圳壹账通智能科技有限公司 | 一种文件下载方法及相关产品 |
CN112437160B (zh) * | 2020-11-25 | 2022-06-07 | 中国电子科技集团公司第二十九研究所 | 一种基于redis实现大文件实时传输处理方法及系统 |
CN112507336A (zh) * | 2020-12-15 | 2021-03-16 | 四川长虹电器股份有限公司 | 基于代码特征和流量行为的服务端恶意程序检测方法 |
CN112667898A (zh) * | 2020-12-30 | 2021-04-16 | 深圳市轱辘车联数据技术有限公司 | 一种资源下载方法、装置、终端设备及存储介质 |
CN113515681A (zh) * | 2021-04-30 | 2021-10-19 | 广东科学技术职业学院 | 基于scrapy框架的房地产数据爬虫方法及装置 |
Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102254027A (zh) * | 2011-07-29 | 2011-11-23 | 四川长虹电器股份有限公司 | 批量获取网页内容的方法 |
CN102314463A (zh) * | 2010-07-07 | 2012-01-11 | 北京瑞信在线系统技术有限公司 | 分布式爬虫系统及其提取网页数据的方法 |
CN102646129A (zh) * | 2012-03-09 | 2012-08-22 | 武汉大学 | 一种主题相关的分布式网络爬虫系统 |
Family Cites Families (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101021848B (zh) * | 2006-02-15 | 2010-08-25 | 鸿富锦精密工业(深圳)有限公司 | 资讯搜索系统及方法 |
-
2013
- 2013-05-24 CN CN201310198673.8A patent/CN103475687B/zh not_active Expired - Fee Related
Patent Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102314463A (zh) * | 2010-07-07 | 2012-01-11 | 北京瑞信在线系统技术有限公司 | 分布式爬虫系统及其提取网页数据的方法 |
CN102254027A (zh) * | 2011-07-29 | 2011-11-23 | 四川长虹电器股份有限公司 | 批量获取网页内容的方法 |
CN102646129A (zh) * | 2012-03-09 | 2012-08-22 | 武汉大学 | 一种主题相关的分布式网络爬虫系统 |
Also Published As
Publication number | Publication date |
---|---|
CN103475687A (zh) | 2013-12-25 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN103475687B (zh) | 用于下载网站数据的分布式方法和系统 | |
CN103475688A (zh) | 用于下载网站数据的分布式方法和系统 | |
CN105320740B (zh) | 微信文章以及公众号的获取方法及获取系统 | |
CN107317724B (zh) | 基于云计算技术的数据采集系统及方法 | |
CN106547914B (zh) | 一种数据采集管理系统及其方法 | |
CN101127038B (zh) | 下载网站静态网页的系统及方法 | |
US9785452B2 (en) | Framework for dependency management and automatic file load in a network environment | |
CN102054028B (zh) | 一种网络爬虫系统实现页面渲染功能的方法 | |
CN108875091B (zh) | 一种统一管理的分布式网络爬虫系统 | |
CN104516982A (zh) | 一种基于Nutch的Web信息提取方法和系统 | |
CN102982162B (zh) | 网页信息的获取系统 | |
CN103605764A (zh) | 一种网络爬虫系统及网络爬虫多任务执行和调度方法 | |
CN102662966B (zh) | 一种面向主题的获取动态页面内容的方法及系统 | |
CN104765592B (zh) | 一种面向网页采集任务的插件管理方法及其装置 | |
CN103473696A (zh) | 一种收集、分析和分发网络商业信息的方法和系统 | |
CN101441629A (zh) | 一种非结构化网页信息的自动采集方法 | |
CN104199893B (zh) | 一种快速将全媒体内容发布的系统和方法 | |
US20210089426A1 (en) | Parsing hierarchical session log data for search and analytics | |
CN113656673A (zh) | 面向广告投放的主从分布内容爬取机器人 | |
CN104317857A (zh) | 一种房屋信息采集服务系统 | |
CN103077196B (zh) | 一种从公网web网站到内网数据库的访问方法 | |
CN105446981B (zh) | 站点地图生成方法、访问方法及装置 | |
CN109446441A (zh) | 一种通用的网络社区可信分布式采集存储系统 | |
CN106911730A (zh) | 一种云盘服务器访问迁移方法和装置 | |
CN107784054B (zh) | 一种页面发布方法和装置 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C14 | Grant of patent or utility model | ||
GR01 | Patent grant | ||
CF01 | Termination of patent right due to non-payment of annual fee |
Granted publication date: 20161228 Termination date: 20190524 |
|
CF01 | Termination of patent right due to non-payment of annual fee |