爬虫工作及管理模块主题爬虫设计
多线程机制
在多线程的设计框架下,爬虫的核心工作部分被封装到独立的线程体里运行。这个线程的活儿很明确:先从爬虫管理员那里领一个新任务,然后调用我们前面提到的各个分析处理模块,对任务进行一番“综合会诊”。为了确保数据库访问的同步与安全,所有线程和数据库的“对话”,都必须通过爬虫管理员这个单一入口来统一调度和管理。
那么,线程每次从等待队列里捞取新URL时,得遵循两个硬性标准:第一,这个URL的预测打分值必须是最高的,确保优先抓取最相关的内容;第二,它的文本长度要尽可能短。这背后其实有个很实际的考虑——短链接往往指向的内容更聚焦,爬取和解析的效率也更高。

去重策略:时间与空间的双重把关
爬虫在工作时,有个大忌:重复访问相同或极度相似的页面。这不仅会让最终用户觉得信息冗余、体验变差,更会无谓地消耗大量宝贵的网络带宽,拖慢整体效率。
避免抓取完全相同的页面,其实相对好办。我们可以在将新发现的URL放入等待队列前,先到各个工作队列里“搜查”一遍。如果没找到一模一样的,就说明这个页面还没被访问过,可以放心加入。因为这种去重是基于同一个URL在时间轴上的唯一性来判断的,所以业界通常称之为“时间上的去重”。
但网络世界更常见也更具挑战性的,是那些内容高度相似但URL不同的“镜像页面”或“转载页面”。这通常是内容被互相拷贝、引用导致的。与前者不同,这类相似性问题是基于页面内容本身的,因此处理起来属于“空间上的去重”。
在我们的主题爬虫设计中,空间去重是这么干的:首先,对网页进行HTML解析,提取出各个标签下的文本内容;接着,对这些文本分词,并统计词频,按从高到低排序;然后,将得到的单词序列转化成一个长字符串;最后,截取这个字符串的前N个字节,用MD5算法计算其散列值。如果两个页面算出来的散列值相同,那我们就有足够把握认定:它们的内容是高度相似的,只抓一个就够了。
遵守规则:爬虫阻止协议(Robots Exclusion Protocol)
一个专业的爬虫,必须懂得“入乡随俗”,尊重网站主人的意愿。这就需要严格遵守爬虫阻止协议,而这个协议,正是通过网站根目录下的那个robots.txt文件(当然,这个文件是网站可选的)来实现的。
打开一个robots.txt文件,你会看到主要有三种类型的行。以“#”开头的行是注释,只起说明作用,没有实际约束力。另外两种行都以冒号结尾,它们是协议的核心:User-Agent用于指明接下来的条款是针对哪个或哪些爬虫的,如果这里写的是“*”,那就意味着对所有爬虫都适用;而Disallow则直接列出了禁止访问的目录或页面路径,一旦某个目录被指定,其下的所有内容都在禁止访问之列。
通过分析这个文件,爬虫就能清楚地知道一个网站里哪些是“禁区”。如果当前准备抓取的页面正好在禁止名单里,爬虫会立刻停止访问,并将对应的URL移入抛弃队列。
另外,为了提高工作效率,我们还可以做一点优化:因为一个网站的所有页面都共享同一个robots.txt文件,所以完全可以把每个网站的禁止规则缓存起来。这样一来,爬虫在访问该站点的任何页面时,就不必每次都劳师动众地去先读取一次robots.txt文件了,直接从缓存里读取规则就行,省时又省力。
