从零构建爬虫系统(二)——面向中小企业的爬虫解决方案

前言

这篇博文主要分享下,如何为中小企业在短时间内搭建出一套爬虫采集系统,技术选型时候应该注意什么,有哪些公开资料可以参考。

本篇博客的目标读者主要是一些有爬虫需求、正在准备组建爬虫团队,从零构建爬虫系统的中小企业或数据部门,整篇博客阅读时间大约十分钟。


从需求谈起

笔者供职的公司是一家从事财税行业的技术公司,目前融资轮次在D轮,主要业务是为代帐公司提供报税服务。目前已为百万家企业提供了报税服务。

在2020年1月时候,笔者所在的数据部门Leader开始提出要为这些企业提供更广泛的数据方面服务,需要抓取相关企业的互联网公开信息,提供给其他应用部门使用。

这类爬虫需求其实在一些初创企业中很常见,爬虫系统并不难做,但想要做好,至少要从以下几个方面评估需求:

  • 爬虫的数据方面需求:
    1. 想要抓取的数据是否只是主营业务的数据补充?抓取后的信息是简单清洗后提供应用类系统展示,还是需要进一步做数据类服务(如数据报告、與情风控)?
    2. 数据应该从哪里抓取?需求方是不是已经明确指定了抓取来源?是否还有更多抓取来源?哪些抓取来源更容易获取到数据?
    3. 数据抓取的周期是什么?需求方对于抓取的时间要求是天,还是实时?
    4. 数据抓取是搜索类抓取,还是深度抓取?如果是搜索类抓取(即在某类网站中通过关键词检索获得相应信息),那么种子关键词的数量和质量怎么样?如果是深度抓取,那么抓取策略是什么?
    5. 对于已经抓取过的数据更新策略是什么?
    6. 对于搜索类抓取,如果搜索不到相应的公司,怎么办?
  • 爬虫的应用方面需求:
    1. 对爬虫数据的实时性要求高不高?是否需要做到实时抓取?
    2. 种子列表的传递使用什么方式进行?是以种子文件还是需要支持接口调度。
    3. 如果是需要为多个第三方应用提供爬虫应用,那么数据存储如何设计?是否需要以任务的形式管理第三方应用提交的爬虫请求?
    4. 爬虫失败抓取时候如何进行捕获错误?如何做日志收集与预警功能?
    5. 网络上有很多关于ip池、cookie池的方案,这些方案大多以接口的形式提供服务,如何设计好多个爬虫应用程序与ip池、账号cookie池?
  • 爬虫在公司整体技术架构中的位置在哪?
    1. 这一方面是日常开发中最容易忽视的部分,因为它涉及到与运维部门、应用部门合作沟通的问题。比如运维方面,爬虫的如何做好敏捷开发?是否使用gitlab/jenkins/docker/rancher/k8s工具链完成构建?
    2. 再比如,爬虫的日志捕获与预警是否可以直接通过logstash等日志收集工具,接入到大数据平台或运维平台进行统一管理?
    3. 爬虫的数据是否需要接入大数据平台,应用统一从数据平台查询?爬虫的任务下发是否需要通过服务形式进行暴露?
  • 对于成本方面有没有要求:
    1. 在软件成本方面,主要体现在代理ip,帐号的购买与使用上。尤其是代理ip的厂商选择上,要先分析好爬虫应用架构、目标网站的反爬策略,再选择适用于自己的代理ip套餐方案。目前主流的代理厂商都提供了http/https、socks、vps等不同代理解决方案,在选择代理厂商的过程中也也好
    2. 在人力成本方面,要考虑到爬虫代码编写中繁琐的解析、入库的工作量。一般爬虫领域分为两个方向,一个是架构方向,另一个是反编译方向。这两个方向最好聘请有经验的工程师牵头实施。架构方向主要职责包括设计调度策略、ip池、cookie池、数据存储等系统层面,反编译方向主要职责包括分析各个目标网站的反爬策略、分析js/Ajax接口、挑选不同目标网站的反反爬工具链。解决这两个问题后,解析、入库等比较繁琐、细节的工作交给初级爬虫工程师负责即可。
  • 在合规性方面有没有做评估:
           1. 对于目标网站,要遵循robots.txt协议,同时最好要提前调研、评估出目标网站的DAU,避免为目标网站带来过多的流量压力,影响目标网站的正常运行。
            2. 对于要抓取的数据,要分析数据是否涉及个人隐私,是否涉及到商业机密,是否需要做脱敏处理。
            3. 对于数据的存储也要尽量做好权限控制,避免造成数据泄露。

在初创企业中,人力资源往往很有限,因此在动手设计系统前,一定要理解企业的整体发展方向、主要经营业务,以及为什么需要抓取数据。只有评估好需求,才有可能避免返工,构建出一个可交付的爬虫系统。


如何做技术选型

笔者认为中小公司在做技术选型时,应至少考虑三个方面:以业务为导向的数据架构,以技术栈为基础的应用架构,以公司内部实际情况的整体技术架构。

  • 业务为导向的数据架构。

首先还是要理解公司想通过爬虫解决什么样的业务问题。比如大多数企业的爬虫需求是通过更多的维度补充自身数据,展示给用户进行查看,而有一些企业则需要将抓取来的数据做二次处理,比如做與情预警、做行业关系图谱、知识图谱、生成行业报告等。

无论是哪种业务需求,我们都需要以业务需求为导向,确定好需求方需要抓取哪些信息,目标网站的数据需求是否真实有效。然后对目标网站的抓取信息做分类,区分出哪些抓取的信息适合存储在一个结果集中,哪些信息适合做结果集中的主键。

  • 以技术栈为基础的应用架构。

这里主要指合理挑选、编排爬虫的技术栈。目前做爬虫主要的工具栈包括以Java语言为主的Webmagic、Apache Nutch,以Python语言为主的Scrapy、PySpider。

Webmagic基本可以满足单机类爬虫,使用多线程的方式完成爬虫请求。如果是小公司,需求不复杂,没有Python技术栈的员工、也没有招人的打算,可以考虑使用Webmagic。他的开发比较简单,只要写好相应的页面解析Processor组件、存储组件Pipeline即可完成一个爬虫。

Apache Nutch相比于Webmagic则要重型得多。其实相比于爬虫,Apache Nutch更适合做一个搜索引擎,抓取和存储半结构化和非结构化的网页数据。Apache Nutch的存储主要有Apache Solr、Apache Hadoop、ES等,解析库有Apache Tika。Apache Nutch解决的需求主要是针对目标网站先进行深度抓取,放在本地的存储后,再使用Tika/Solr进行解析与检索。

相比于Java技术栈,Scrapy是中小企业做爬虫最划得来的技术栈选择。只需要编写Spider中parse方法、pipeline方法,即可完成一个单机版本的爬虫。Scrapy提供的技术栈生态非常丰富,使用Scrapy-redis可以通过共享内存队列的方式实现分布式爬虫,使用scrapyd可以更好的托管爬虫、实现种子列表的接口调度,甚至还有Scrapy-cluster提供开箱即用的整套爬虫服务。

使用Scrapy及相关的技术栈,能基本实现以下功能:

  1. 通过分布式的方式,增加机器资源,即可增加抓取吞吐量。
  2. 使用缓存消息队列如kafka,为第三方应用提供数据传输。
  3. 支持接口调度的形式,接受爬虫的种子列表。

基本上,选择的技术栈能支持以上几个功能,就可以满足中小企业的日常爬虫需求了。

  • 以公司内部实际情况的整体技术架构。

这一部分主要要从两个角度进行考虑,一个是需要与爬虫发生数据交换的应用系统角度,另一个是公司的DevOps与运维成熟度角度。

我们首先说第一个角度。

做爬虫系统一定是要关注它的输入与输出的,因为抓取到的数据只有能被用起来,才能体现出它的价值。

一般比较简单的开源爬虫框架,输入的种子列表都是一个文件,然后通过命令行启动完成抓取。但是这远远不能满足日常的抓取需求,因为不可能说日常抓取都需要以文本文件的形式,上传到爬虫服务器然后手工启动爬虫运行,这显然不够灵活。目前中小互联网公司在各个应用系统间完成调度无非是两种方式,一个是被调用方提供restful api接口,另一种方式是以消息队列(如mq,kafka)进行消息传递。这里无论哪种方式,我们都假设这里采用异步方式进行调度。

对于爬虫系统来说,两种方式都可以,但是通过restful api的形式接受会相对更容易、更灵活一些。如果使用消息队列的方式传递种子列表,我们就要考虑爬虫端需要有一个consumer不断从消息队列中取消息,然后将消息转换为种子列表的形式,再放入到爬虫的种子列表队列中。这在实现上可能会比较麻烦,因为涉及到了一个消息的转化过程,而且对爬虫框架的二次开发能力也有一定要求。

比较简单的方法是通过restful api的方式。使用Flask/Django Restful/Spring Boot增加一层service,将接口设计好,外部应用根据需求调度接口,接口将请求转化为特定的url,插入到爬虫的种子队列存储介质中,比如redis,这样就可以较好的完成种子列表的输入。

输出方面,要按照企业的实际情况来看。一般来说爬虫的pipeline只负责很简单的清洗与存储,对于比较复杂、繁琐的清洗需求,一般是放在后边应用来做。比如,如果是只给一个应用系统的Mysql数据库提供数据的话,那可以直接在爬虫中写一个Mysql的Pipeline。如果是需要给多个系统提供数据的话,那就要考虑将爬虫数据统一存储,然后对外提供查询能力。如果抓取的数据更加复杂,那就要考虑增加一层缓存如mq或kafka,然后通过kettle,python脚本或流式工具比如Apache NIFI/Apache Storm/Apache Flink/Apache Spark等进行数据处理,将数据处理结果推送到大数据平台,再对外提供查询能力。

总结下来,爬虫系统的输入端最好能提供一个restful的能力,要便于外部应用灵活调度。输出端要根据清洗难度、项目背景做好设计,使用合理的方式清洗、存储数据。

另一方面,公司的DevOps与运维能力对爬虫系统的研发也至关重要。

爬虫系统的研发很有可能是一个持续开发、持续集成的工作。目标网站的页面变动,反爬手段都有可能涉及到爬虫代码的重构与上线。

如果公司有一定的运维能力,使用docker/k8s发布应用,要尽量使用这些工具进行爬虫代码的构建。同时爬虫的ip代理、服务器、网络资源等成本的控制也应该与公司运维部门做好沟通,防止成本超标。

爬虫的日志也应该做好管理,因为一个目标网站的页面变动往往是事后通过分析日志来定位发现的。如果能做好爬虫错误日志的监控和预警,能尽早定位到问题,修改代码,然后重构上线,避免影响线上业务。

结语

完成一个爬虫系统需要考虑的东西有很多,在需求方面,要从公司的实际业务入手,在技术选型方面,要从数据架构、应用架构、整体技术架构三个方面进行考虑。做好以上两个方面,才能较好的完成一个稳定的、健壮的爬虫系统。


公开资料

1、崔庆才的书籍、以及夜幕团队的一些文章。

2、Scrapy 官方文档。

你可能感兴趣的:(项目经验与工作难题,爬虫)