在大数据时代,数据采集或网络爬虫似乎是每个程序员的必备技能,一般情况下,工程师会通过Python爬虫框架快速的编写出爬虫程序对网页数据抓取,不过在大规模数据采集的时候就不是一个简简单单的爬虫程序了。例如,分布式爬虫系统,在为我们的舆情系统(gitee.com/stonedtx/yuqing)、开源情报系统(gitee.com/stonedtx/open-source-intelligence) 提供大量的数据支撑。
在此,向大家介绍我们由Java编写的系统能够每秒可以访问几十万个网页的分布式网络爬虫系统!
在这篇文章中,将与大家分享多年来我们在构建与优化爬虫方面所获得的经验以及教训。
这是我们大规模分布式爬虫系统的系统(操作界面),自己称之为:爬虫工厂。
这是我们即将上线“开源情报”系统里的“数据管理” (数据中台)子系统。
经过这么多项目的实战经历和经验,同时与市场和客户不断的碰撞,造就了我们强大的数据采集能力。
一、编程语言
在为项目选择编程语言时,许多因素都会影响到我们的最终决策。中间我们尝试过python和Go语言的爬虫和分布式爬虫的方案。我们在内部专业知识、生态系统,这几个方面寻找“完美”的编程语言方案。最终,我们认为Java是我们的最佳选择,原因如下:
1.内部专业知识:我们的团队成员拥有丰富的Java专业知识,有好几个Java开发“老司机”都是10年、15年、20年的经验,他们都在分布式系统和网络高并发、海量数据存储开发方面有丰富的实战经验。
2.现有软件框架:大规模的网络爬虫需要建立在久经考验的强大、可扩展且安全的网络、系统和实用程序模块之上。Java拥有最活跃的开源生态系统,特别是在网络和分布式应用程序方面。Netty、SpringBoot和Google Guava等软件包证明Java生态系统拥有高质量的开源模块。
3.现有的项目集成:Hadoop、Cassandra、Kafka、Elasticsearch全都是用Java开发的大型分布式系统项目,因为这个生态系统给我们带来了丰富又强大的基础以及灵感和先例。从而使得用Java开发高性能数据驱动应用程序的过程变得更加简单且经济实惠。
4.Java的动态语言:在我们最新的分布爬虫系统中采用了动态语言,我们把动态语言代码通过模板生成,并存储在MySQL中,这样对大量的爬虫通过可视化和低代码的方式大大降低的维护成本和爬虫开发成本。
5.原始性能和可靠性:在性能和可靠性方面,Java拥有静态类型,强大的垃圾收集以及久经实战考验的虚拟机等最重要的特性。
虽然核心网络爬虫引擎是用Java编写的,我们也使用其他语言(例如Python和Node.js)来编写自然语言处理、深度学习算法、监视、报告和管道的其他部分的子系统。
我们的分布式爬虫集群采用了无单点的架构,工作负载在独立的无状态节点上进行分割和分布,这可以消除大规模分布式系统的灾难(单点故障)。另外,该架构允许我们逐个节点更新和升级底层软件,而不会中断整个操作。
二、请求速率与访问安全
网站的主要设计目的是供人类访问,一位普通用户每分钟只能浏览很少的页面。网络爬虫每秒能够访问数千甚至数百万个网页,因此,如果不小心,网络爬虫很容易在很短的时间内耗尽网站资源,造成破坏性的后果。而且,一个普通的网站会有多个机器人同时抓取,所以这个问题会被放大。
因此,每个网络爬虫也有责任对自己的请求速率进行限制,换句话说,确保连续两次访问之间有适当的延迟,这项工作不容许出错,否则对请求网站和自己都会产生不利的反应。
三、缓存为王道
在构建大规模分布式数据应用系统的情况下,系统缓存是必不可少的,特别是网络输入&输出频繁且开销更大的情况下。
例如场景1:在大规模网络爬取的情况下,为了避免数据重复抓取以及后续的数据重复处理,那么就需要把每个URL获取,并且存储下来。因此,你需要构建一个分布式的预读缓存,能够持有并定期更新数百万个网站的上亿的URL地址仓库。
例如场景2:减少dns的请求,提高数据采集的性能。对于绝大多数URL,你需要至少执行一次DNS解析才能下载,这会增加每秒数千次的查询。因此,DNS服务器必然会限制你的访问,或者在过重的负荷下崩溃。无论是哪种情况都会导致爬虫停止,唯一的解决办法就是尽可能缓存DNS解析结果,并最大限度地减少不必要的查询。
四、解析HTML
爬虫的基本任务之一就是从它访问的每个页面中提取所需要的数据。如果大规模的数据爬取,那么最好有一个高性能的HTML解析器,因为你需要提取大量的链接和元数据。大多数HTML解析库会优先考虑简单性、易用性和通用性,一般来讲这是正确的设计。由于我们需要高速的链接提取,所以最终我们决定编写自己的解析器,并针对查找链接和一些原始DOM的查询功能进行了优化。HTML解析器还需要具有弹性,经过全面的测试,并且能够处理大量出现的异常情况,因为并非每个HTML文档都是有效的。
我们目前即将开源的数据采集系统,里面集成了微软开源playwright(https://playwright.dev)的js渲染解析引擎。这样在开发爬虫的过程中我们就不需要去考虑js网页数据的问题了,大大提高了我们对网站爬虫的开发效率。
五、网络与系统的优化
通常操作系统的默认配置无法处理大规模网络爬虫的网络需求。通常我们需要根据具体情况,优化操作系统的网络堆栈,使其发挥最大潜力。对于大规模的网络爬虫来说,优化的目标在于最大化吞吐量和打开连接的数量。
以下是我们经常会实际遇到需要优化的问题和场景:
1.Linux系统性能参数
一般Linux性能调优都用什么工具? - 知乎
2.Web服务器性能优化
java web服务器性能优化策略? - 知乎
3.Java JVM性能优化
Java性能优化之JVM GC(垃圾回收机制) - 知乎
开源项目地址:
目前我们已经将上述技术实践开源,请关注我们发布的开源项目。
开源免费舆情监测网络监控系统: 思通舆情 是一款开源免费的舆情系统,支持本地化部署。支持对海量的舆情数据进行交叉分析和深度挖掘,为用户提供全面的舆情数据,专业的舆情分析,快速的舆情处理等服务,提升企业品牌价值和风控能力。#舆情系统#舆情监测#网络舆情#开源舆情#免费舆情#舆情分析https://gitee.com/stonedtx/yuqing