Skip to content

Crawler

wxyyxc1992 edited this page Feb 13, 2019 · 1 revision

浅论复杂智能爬虫的挑战与设计

业务透明、执行抽象

爬虫是数据抓取的重要手段之一,而以 ScrapyCrawler4jNutch 为代表的开源框架能够帮我们快速构建分布式爬虫系统;就笔者浅见,我们在开发大规模爬虫系统时可能会面临以下挑战:

  • 网页抓取:最简单的抓取就是使用 HTTPClient 或者 fetch 或者 request 这样的 HTTP 客户端。现在随着单页应用这样富客户端应用的流行,我们可以使用 Selenium、PhantomJS 这样的 Headless Brwoser 来动态执行脚本进行渲染。
  • 网页解析:对于网页内容的抽取与解析是个很麻烦的问题,DOM4j、Cherrio、beautifulsoup 这些为我们提供了基本的解析功能。笔者也尝试过构建全配置型的爬虫,类似于 Web-Scraper,然而还是输给了复杂多变,多层嵌套的 iFrame 页面。这里笔者秉持代码即配置的理念,对于使用配置来声明的内建复杂度比较低,但是对于那些业务复杂度较高的网页,整体复杂度会以几何倍数增长。而使用代码来声明其内建复杂度与门槛相对较高,但是能较好地处理业务复杂度较高的网页。笔者在构思未来的交互式爬虫生成界面时,也是希望借鉴 FaaS 的思路,直接使用代码声明整个解析流程,而不是使用配置。
  • 反爬虫对抗:类似于淘宝这样的主流网站基本上都有反爬虫机制,它们会对于请求频次、请求地址、请求行为与目标的连贯性等多个维度进行分析,从而判断请求者是爬虫还是真实用户。我们常见的方式就是使用多 IP 或者多代理来避免同一源的频繁请求,或者可以借鉴 GAN 或者增强学习的思路,让爬虫自动地针对目标网站的反爬虫策略进行自我升级与改造。另一个常见的反爬虫方式就是验证码,从最初的混淆图片到现在常见的拖动式验证码都是不小的障碍,我们可以使用图片中文字提取、模拟用户行为等方式来尝试绕过。
  • 分布式调度:单机的吞吐量和性能总是有瓶颈的,而分布式爬虫与其他分布式系统一样,需要考虑分布式治理、数据一致性、任务调度等多个方面的问题。笔者个人的感觉是应该将爬虫的工作节点尽可能地无状态化,以 Redis 或者 Consul 这样的能保证高可用性的中心存储存放整个爬虫集群的状态。
  • 在线有价值页面预判:Google 经典的 PageRank 能够基于网络中的连接信息判断某个 URL 的有价值程度,从而优先索引或者抓取有价值的页面。而像 Anthelion 这样的智能解析工具能够基于之前的页面提取内容的有价值程度来预判某个 URL 是否有抓取的必要。
  • 页面内容提取与存储:对于网页中的结构化或者非结构化的内容实体提取是自然语言处理中的常见任务之一,而自动从海量数据中提取出有意义的内容也涉及到机器学习、大数据处理等多个领域的知识。我们可以使用 Hadoop MapReduce、Spark、Flink 等离线或者流式计算引擎来处理海量数据,使用词嵌入、主题模型、LSTM 等等机器学习技术来分析文本,可以使用 HBase、ElasticSearch 来存储或者对文本建立索引。

笔者本意并非想重新造个轮子,不过在改造我司某个简单的命令式爬虫的过程中发现,很多的调度与监控操作应该交由框架完成。Node.js 在开发大规模分布式应用程序的一致性(JavaScript 的不规范)与性能可能不如 Java 或者 Go。但是正如笔者在上文中提及,JavaScript 的优势在于能够通过同构代码同时运行在客户端与服务端,那么未来对于解析这一步完全可以在客户端调试完毕然后直接将代码运行在服务端,这对于构建灵活多变的解析可能有一定意义。

总而言之,我只是想有一个可扩展、能监控、简单易用的爬虫框架,所以我快速撸了一个 declarative-crawler,目前只是处于原型阶段,尚未发布到 npm 中;希望有兴趣的大大不吝赐教,特别是发现了有同类型的框架可以吱一声,我看看能不能拿来主义,多多学习。

Clone this wiki locally