我们从爬取1000亿个网页中学到了什么?

现如今,爬取网页看起来似乎是一件很简单的事。有很多开源框架或库、可视化爬取工具和数据提取工具,利用这些工具可以很容易地从网站上爬取数据。但是,当你想大规模爬取网站时,事情就变得棘手起来。其中包括应对不断变化的网站格式、构建可伸缩的爬虫基础框架并保持吞吐量,与此同时还要挫败网站反机器人的手段以及维护数据质量。在这篇文章中,流行 Python 爬虫框架 Scrapy 开发者 Scrapinghub 分享了大规模爬取产品数据时将面临的主要挑战,以及他们爬取 1000 亿个网页后的经验之谈。

我们从爬取1000亿个网页中学到了什么?

  • 策划编辑 | Natalie
  • 编译 | 无明
  • 编辑 | Vincent
  • 微信公众号“AI 前线”,(ID:ai-front)

Scrapinghub 成立于 2010 年,是一家领先的数据公司,当今最强大、最受欢迎的网络爬取框架 Scrapy 就是由它开发的。目前,Scrapinghub 每个月为全球很多大型的电子商务公司爬取 80 亿个网页(其中有 30 亿个是产品页面)。

在进行大规模爬取时哪些东西是最重要的?

与标准的爬虫应用程序不同,大规模爬取电子商务产品数据需要面临一系列独特的挑战,这些挑战让爬取网页变得更加困难。

这些挑战可以被归结为两类:速度和数据质量。

因为时间通常是一个限制性的约束条件,所以在进行大规模爬取时要求爬虫以非常快的速度进行爬取,同时又不影响数据质量。这种对速度的极限要求使得爬取大量产品数据变得极具挑战性。

挑战之一:凌乱的代码和不断变化的网页格式

很显然,凌乱的代码和不断变化的网页格式是在大规模爬取数据时将面临的最大挑战。不一定是因为任务的复杂性,而是你要在这上面所花费的时间和资源。

如果你做过网店的爬虫,就会知道,在网店的网页中,凌乱的代码泛滥成灾。除了 HTML 格式问题或偶尔出现的字符编码问题之外,还有其他很多问题。多年来,我们遇到了各种各样的问题——滥用 HTTP 响应码、糟糕的 JavaScripts 或滥用 Ajax:

  • 网店在停止销售某些产品时会删除相应的产品页面,但在网站升级后,404 错误处理程序却返回了 200 响应码。
  • 错误地转义了 JSON 数据,导致某些页面上的 JavaScript 代码无法正常运行(例如’b0rk’d’),你不得不使用正则表达式来爬取数据。
  • 滥用 Ajax,以至于你只能在渲染页面(导致爬取变慢)或模拟 API 调用(导致更多的开发工作量)后才能抓取到你想要的信息。

这些凌乱的代码不仅是你开发爬虫时的痛点,也会影响到那些可视化爬虫工具或自动爬取工具。

在进行大规模爬取时,除了要应对这些凌乱的代码,还要面临网站不断发生变化所带来的挑战。根据常规经验,目标网站一般每过 2-3 个月就会修改一次,你的爬虫就会出问题(导致爬取覆盖率或质量下降)。

这听起来可能没什么大不了的,但在进行大规模爬取时,这些问题积少成多,就会带来大麻烦。Scrapinghub 的一个大型电子商务项目使用约 4,000 个爬虫爬取约 1,000 个电子商务网站,这意味着他们每天会遇到 20-30 个爬虫失败。

不同区域和多语言网站的网页布局的变化、A/B 测试、产品套件和定价的变化也给爬虫带来了更多难题。

没有简单的解决方案

对于这些问题,并没有什么万能的灵丹妙药。很多时候,在扩大规模时往项目中增加更多的资源。以上一个项目为例,该项目的团队由 18 名全职爬虫工程师和 3 名专职 QA 工程师组成,以确保能够源源不断地向客户始提供数据。

但是,从经验来看,你的团队仍然要学会如何开发更强大的爬虫,用它们来检测和处理各种诡异的网页格式。

最好是只开发一个可以处理不同页面布局的爬虫,而不是为不同的页面布局开发多个爬虫,爬虫的可配置下越高越好。

虽然这样会让你的爬虫变复杂(我们的一些爬虫代码长达数千行),但也更容易维护。

大多数公司每天都需要爬取产品数据,因为工程团队要修复爬虫问题而不得不等上几天,这可不是个好主意。在出现这种情况时,Scrapinghub 使用基于机器学习的数据提取工具。这种基于 ML 的提取工具可自动识别目标网站上的目标字段(产品名称、价格、货币类型、图像、SKU 等)并返回所需的结果。

挑战之二:可伸缩架构

第二个挑战是构建一个可伸缩的爬虫基础架构,可以随着请求数量的增加而伸缩,而不会影响到性能。

在大规模爬取产品数据时,一个只能串行化爬取数据的简单网络爬虫是不够的。通常,串行化的爬虫在一个循环中一个接一个地发出请求,每个请求需要 2-3 秒才能完成。

如果你的爬虫每天发出的请求少于 40,000 个(每 2 秒请求一次相当于每天 43,200 个请求),那么使用这种方法就足够了。但是,在此之后,你需要转换到一种爬虫架构,这样才能每天爬取数百万个网页,而不会降低性能。

爬取速度是大规模爬取产品数据的关键。你要确保能够在给定的时间内(通常为一天)找到并爬取所有必需的产品页面。为此,你需要执行以下操作:

实现产品发现和产品抓取的分离

要大规模爬取产品数据,需要将产品发现爬虫与产品抓取爬虫分开。

用于产品发现的爬虫主要负责导航到目标产品类别(或“货架”),并为产品提取爬虫保存该类别下的产品 URL。在产品发现爬虫将产品 URL 添加到队列后,产品抓取爬虫会从该产品页面爬取目标数据。

Scrapinghub 为此开发了 Frontera(https://github.com/scrapinghub/frontera),并将其开源,虽然 Frontera 最初被设计与 Scrapy 一起使用,但也可以与其他爬虫框架或独立项目一起使用。在这篇文章(https://blog.scrapinghub.com/2015/04/22/frontera-the-brain-behind-the-crawls/)中,我们分享了如何使用 Frontera 大规模爬取 HackerNews。

为产品爬取分配更多资源

每个产品类别可能包含 10 到 100 个产品,并且爬取产品数据比爬取产品 URL 更耗费资源,因此产品发现爬虫通常比产品抓取爬虫运行得更快。所以,你需要为每个发现爬虫配备多个抓取爬虫。根据经验,大约每 100,000 个网页需要配备一个单独的抓取爬虫。

挑战之三:保持吞吐量

大规模爬取可以比作一级方程式赛车,你的终极目标是从车上卸掉每一克不必要的重量,并以速度的名义榨取发动机最后那一点马力。大规模网页爬取也是如此。

在爬取大量数据时,你始终在寻找最小化请求周期时间的方法,并最大限度地提高爬虫性能,所有这些都是为了能为每个请求减少几毫秒的时间。

你的团队需要深入了解正在使用的爬虫框架、代理和硬件,才能调整它们以获得最佳性能。除此之外,还需要关注:

爬取效率

在进行大规模爬取时,应该尽可能只爬取必要的数据。额外的请求或数据抓取都会降低爬取网站的速度。在设计爬虫时,请记住以下几点:

  • 只在逼不得已的情况下才使用 headless 浏览器(如 Splash 或 Puppeteer)来解析 JavaScript,因为使用 headless 浏览器解析 JavaScript 相当耗费资源,会严重影响爬取的速度。
  • 如果可以从产品页面(如产品名称、价格、评级等)获取所需数据而无需请求每个产品页面,那么就不要请求产品页面。
  • 除非真的需要,否则不要请求或抓取图像。

挑战之四:反机器人措施

如果你正在大规模爬取电子商务网站,肯定会碰到使用反机器人措施的网站。

大多数小型网站使用基本的反机器人措施(比如禁掉频繁访问的 IP 地址)。而像亚马逊这样大型的电子商务网站会使用像 Distil Networks、Incapsula 或 Akamai 这些复杂的反机器人措施,这让爬取数据变得更加困难。

代理

因此,在进行大规模产品数据爬取时,首先需要考虑使用代理。你需要大量的代理,并且需要实现 IP 轮换、请求限制、会话管理和黑名单逻辑,防止代理被禁。

除非你已经或者愿意养一个庞大的团队来管理代理,否则应该将这部分爬取过程外包出去。现在有大量的代理服务,他们提供了不同级别的服务。

我们的建议是与代理提供商合作,代理提供商可以为代理配置提供单个端点,并隐藏管理代理的复杂性。大规模爬取非常耗费资源,所以不应该自己重复发明轮子,比如开发和维护自己的内部代理管理基础设施。

代理之外

不过,仅仅使用代理服务还不足以确保你可以在大型的电子商务网站上规避反机器人措施,越来越多的网站正在使用复杂的反机器人措施来监控你的爬虫。

这些反机器人措施不仅会让爬取电子商务网站变得更加困难,如果处理不好,会严重影响爬取工具的性能。

在这些反机器人措施中,有很大一部分使用 JavaScript 来判别请求是来自爬虫还是人类(JavaScript 引擎检查、字体枚举、WebGL 和 Canvas 等)。

不过之前已经提到,在进行大规模爬取时,要尽量限制使用 headless 浏览器(如 Splash 或 Puppeteer)来解析 JavaScript,因为它们非常耗费资源,并且会降低爬取网页的速度。

因此,为了确保爬虫的吞吐量,以便每天提供必要的产品数据,你通常需要精心对网站的反机器人措施进行反向工程,在不使用 headless 浏览器的情况下让你的爬虫搞定一切。

挑战之五:数据质量

从数据科学家的角度来看,爬虫项目最重要的考虑因素是所提取数据的质量,而大规模爬取只会让对数据质量的关注变得更加重要。

每天提取数百万个数据点,就无法手动验证所有数据是否干净且完好无损。脏数据或不完整的数据很容易进入到你的数据源并破坏你的数据分析工作。

在爬取同一网站(不同语言,地区等)或不同网站相同产品的多个版本时,尤其需要考虑数据质量问题。

在爬虫的设计阶段,需要进行严格的 QA 过程,爬虫的代码需要经过严格的评审和测试,确保可以以最可靠的方式提取所需的数据。确保高质量数据的最佳方法是开发自动化 QA 监控系统。

作为数据爬取项目的一部分,需要规划和开发一个监控系统,在发现数据不一致或发生错误时可以发出告警。在 Scrapinghub,我们开发了机器学习算法,用于检测:

  • 数据验证错误——每个数据项都有定义好的数据类型,它们的值都遵循一致的模式。我们的数据验证算法可以标记出与数据类型的预期不一致的数据项,QA 团队将手动检查这些数据,并发出告警或将其标记为错误。
  • 产品差异错误——从同一网站的多个版本(不同语言、地区等)爬取相同的产品数据时,一些变量(如产品重量或尺寸)可能会有不同的值。这可能是网站的反机器人措施为爬虫提供的伪造信息。同样,你需要有适当的算法来识别和标记此类数据。
  • 数据量不一致性——另一个关键的监控动作是检测异常的返回数据量。如果出现异常,可能是因为网站已经发生了变更,或者网站向你的爬取工具提供了伪造信息。
  • 网站变更——目标网站发生的结构性变更是导致爬取工具崩溃的主要原因。我们的专用监控系统对此进行监控,它会频繁地检查目标网站,确保自上次爬取以来没有发生任何变更。如果发生变更,它会发送通知。

总  结

本文介绍了在进行大规模爬取产品数据时需要面对的一系列独特的挑战。对于那些有兴趣了解大规模网站爬取的人,可以进一步参阅 Enterprise Web Scraping: A Guide to Scraping the Web at Scale(https://info.scrapinghub.com/enterprise-web-scraping-scraping-at-scale)。

英文原文:

https://blog.scrapinghub.com/web-scraping-at-scale-lessons-learned-scraping-100-billion-products-pages

本文为专栏文章,来自:AI前线,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/57150.html 。

(0)
AI前线的头像AI前线专栏
上一篇 2018-07-16 06:06
下一篇 2018-08-08 21:21

相关文章

关注我们
关注我们
分享本页
返回顶部