当前位置: 首页 > 科技观察

如何设计一个复杂的分布式爬虫系统?

时间:2023-03-16 21:20:53 科技观察

一个复杂的分布式爬虫系统由很多模块组成,每个模块都是一个独立的服务(SOA架构),所有服务都注册到Zookeeper进行统一管理和在线扩展。模块通过thrift(或protobuf,或soup,或json等)协议进行交互和通信。Zookeeper负责管理系统中的所有服务,配置信息的简单同步,以及同一服务不同副本之间的负载均衡。它还具有可以实现业务模块热插拔的优点。URLManager是爬虫系统的核心。负责URL重要性排序、分配、调度和任务分配。单个爬虫爬完一批URL后,会向URLManager请求一批新的URL。一般来说,一个抓取任务包含几千到一万个URL,而这些URL必须来自不同的主机,这样一个主机不会在短时间内造成高峰。ContentAcceptor负责从爬虫中收集页面或其他内容。爬虫一般会将一批爬取的页面,比如一百个页面,压缩成一个文件发送给ContentAcceptor。ContentAcceptor收到后解压,存储在分布式文件系统或分布式数据库中,或者直接发送给ContentParser进行解析。CaptchaHandler负责处理爬虫发送的验证码。通过自动验证码识别器,或者缓存之前识别过的验证码,或者通过人工编码服务等,识别出正确的编码返回给爬虫。爬虫按照Defined爬取逻辑进行爬取。RobotsFileHandler负责对robots.txt文件进行处理和分析,然后缓存起来提供给ContentParser和URLManager禁止抓取的信息。原则上,一个行为良好的爬虫应该遵守机器人协议。但是,现在的大数据公司,为了获取更多的数据,基本不遵守这个协议。robots文件的爬取也是由分布式爬虫通过URLManager作为爬取类型完成的。ProxyManager负责管理系统使用的所有Proxies。说白了就是负责管理可以用来爬取的IP。爬虫请求ProxyManager获取一批ProxyIP,然后每次访问时使用不同的IP。如果某个IP被屏蔽,会立即反馈给ProxyManager,ProxyManager会根据哪个主机屏蔽了哪个IP,进行实时智能调度。管理员负责管理整个分布式爬虫系统。管理员通过这个界面对系统进行配置,启动和停止一个服务,删除错误的结果,了解系统的运行情况等等。各种类型的爬取任务,比如爬取一个页面的URL(NormalCrawler),爬取前需要用户名和密码注册(SessionCrawler),爬取时输入验证码(CaptchaCrawler),爬取需要不同类型的爬虫像需要模拟用户行为来爬取(Simulator),像移动页面和内容一样爬取(MobileCrawler),像App中的内容一样爬取(AppCrawler)。当然也可以开发一个通用的爬虫,然后根据不同的类型实现不同的策略,但是这样的程序中的代码比较复杂,可扩展性和可维护性不强。爬虫内部的爬虫逻辑是通过解释配置文件CrawlLogic中的命令来实现的,而不是将爬虫逻辑硬编码在爬虫程序中。对于复杂的爬取逻辑,甚至可以通过编写代码的插件来实现。ContentParser根据URLExtractionRules提取需要爬取的URL,因为焦点爬虫只需要爬取需要的数据,并不是网站的每一个URL都需要爬取。ContentParser也会根据FieldExtractionRules提取感兴趣的数据,然后对原始数据进行结构化处理。由于动态生成的页面很多,很多数据都是通过Javascript展示的,需要JavascriptEngine来帮助分析页面。这里需要提一下,有些页面会大量使用AJAX来实时获取和展示数据,所以需要一种能够解释Javascript的爬虫类型来处理这些AJAX情况。为了监控整个系统的健康和性能,需要Monitor系统。为了调试系统,保证系统的安全,需要Logger系统。有了这些,系统就比较完整了。所有数据都会存储在分布式文件系统或数据库中,这些数据包括URL(URLRepo)、页面(PageRepo)和字段(FieldRepo),至于选择什么样的存储系统,你可以根据你现有的基础架构和熟悉到什么程度。为了扩大爬虫系统的吞吐量,每个服务都可以横向扩展,包括水平复制,或者按URL分片。因为使用了Zookeeper,为一个服务添加副本只需要启动该服务,剩下的Zookeeper会自动处理。这只是一个复杂的分布式爬虫系统的通用框架。在实际实现中还有很多细节需要处理。这时候之前爬虫系统踩坑的经验就很重要了。