9.1 网络爬虫与框架

简单来说,网络爬虫是互联网终端用户的模仿者。它模仿的主要对象有两个,一个是坐在计算器前使用网络浏览器访问互联网内容的人类用户,另一个是网络浏览器。网络爬虫会模仿人类用户输入互联网中某个网站的网络地址,并试图访问该网站上的内容,还会模仿网络浏览器根据给定的网络地址去下载相应的网络页面(以下简称网页)。在下载到对应的网页之后,网络爬虫会根据预设的规则去分析和筛选网页中的内容。这些被筛选出的内容会马上被进行特定的处理,并以某种形式留存下来。与此同时,网络爬虫还会像人类用户点击某个网页中他感兴趣的链接那样,继续访问和下载相关联的其他网页,然后再对这些网页的内容进行同样或类似的处理。

依据上面这几句概述,读者可能已经意识到:网络爬虫实际上就是一个爬取和分析网页的程序。它应该去自动下载使用者需要的网页,并根据使用者的意愿从中提取出相关的链接、筛选出可用的内容,以及分析、统计或存储它们。注意,这其中的关键词是“自动”和“根据意愿”。“自动”的含义是,网络爬虫在被启动后应该自己完成整个网页爬取过程而无需人工干预,并且还能够在过程结束之后自动停止。而“根据意愿”则是说,网络爬虫应该最大限度地允许使用者对其爬取过程进行定制。

乍一看,要做到自动地爬取貌似并不困难。我们只需让网络爬虫根据相关的网络地址不断地下载对应的网页即可。但是,窥探其中,却有很多细节需要我们进行特别的处理。

  • 有效网络地址的判定。

  • 有效网络地址的边界定义和校验。

  • 重复的网络地址的过滤。

  • 非直接的网络地址的发现和提取。

在这些细节当中,有的是比较容易处理的,而有些则需要额外的解决方案。例如,我们都知道,基于HTML的网页中可以包含button标签。若我们想在终端用户点击该按钮的时候使网络浏览器跳转到另一个网页,则可以找到很多种方法。其中,非常常用的一个方法就是为该标签添加onclick属性并把一些JavaScript语言的代码作为它的值。虽然这个方法如此常用,但是我们想让网络爬虫可以从中提取出有效的网络地址却是比较困难的。因为这涉及了对相应的JavaScript语言程序的理解。可以作为onclick属性的值的JavaScript语言代码的书写方法繁多。要想让网络爬虫完全理解它们,恐怕就必须要用到某个JavaScript语言解析器的实现了。

另一方面,由于互联网对人们生活和工作的全面渗透,我们可以通过各种途径了解到的各式各样的网络爬虫实现。它们都有着截然不同且复杂独特的逻辑。这些复杂的逻辑主要针对的是如下几个方面。

  • 在根据网络地址组装HTTP请求时需要为其设定的各种各样的头信息和主体内容。

  • 对网页中的链接和内容进行筛选时需要用到的各种条件。这里所说的条件包括提取条件、过滤条件和分类条件,等等。

  • 处理筛选出的内容时涉及的各种处理方法和步骤。

这些逻辑绝大多数都与网络爬虫使用者当时的意愿有关。换句话说,它们都与具体的使用目的有着紧密的联系。也许它们并不应该作为网络爬虫的核心功能。

经过上面的分析,我发现:我们更应该编写一个容易被定制和扩展的网络爬虫框架,而不是一个针对特定网页爬取目的的网络爬虫实现。这样才能使该应用程序被称为一个实用工具。

好了,既然我们撇去了那些容易喧宾夺主的特定功能,也明确了本章编写的应用程序应该被作为一个网络爬虫框架而存在,那么接下来我们就应该搞清楚这个框架都应该或可以做哪些事。这也能够让我们进一步明确它的功能、用途和意义。