同福

Python做个搜索引擎(4)网页蜘蛛之工作原理【20201009】

介绍

介绍

前面几堂课我们已经掌握了通过Python编程操作MySQL数据库和ElasticSearch搜索引擎的技巧,今天开始就可以正式编写代码了。

搜索引擎分为两个部分,一个是网页蜘蛛,负责爬取网站的网页内容并且存入MySQL数据库当中,同时同步写入到ElasticSearch搜索引擎里面;另外一个是搜索界面,负责从ElasticSearch搜索引擎里面根据查询关键字找出匹配项,然后根据匹配项的主键去MySQL数据库里查询出原始数据,最后展示给用户。

这一课我们将开始进行网页蜘蛛程序的编写,这个网页蜘蛛程序是关键,也是很复杂的,对于新手来说会有一定难度。因此,福哥会将程序的分开多个部分,童鞋们可以一点一点地学习网页蜘蛛的编写。

分析

首先,我们要想一下,我们的MySQL数据表websites里存放了很多的域名,每个域名都对应这一个网站,那么我们如果要对这些域名对应的网站的网页进行爬取的话,是需要一个顺序的。因为,如果没有这样一个顺序,我们将只会反复对排在前面的域名进行爬取,而排在后面的域名就太可怜了!

在websites表里有lastFetchDT(最后爬取时间)和nextFetchDT(下次爬取时间)两个字段,我们可以根据这两个字段进行排序,让nextFetchDT最早的域名排在前面(因为nextFetchDT表示计划爬取时间,越早的越应该先爬取),让lastFetchDT最晚的域名排在前面(因为lastFetchDT表示最后爬取时间,越早的就应该放到后面重新排队)。

设计

种子网站

因为默认情况下,我们的websites数据表是空的。既然是空的,我们就无法开始网站网页的爬取处理了。所以,我们需要先手动插入一些“种子”网站域名,这些网站域名会被先进行爬取,在爬取的过程中可以通过网站的“外链”找到新的网站域名,我们再保存这些新的网站域名到websites数据表里。

这样我们的搜索引擎里面的域名就会越来越多了,就好像我们的“种子”网站域名发芽结果了一样!

下面福哥提供了几个“种子”网站域名的插入SQL语句:

INSERT INTO websites (domainName, weight, createDT, nextFetchDT) VALUES ('tongfu.net', 1, now(), now());
INSERT INTO websites (domainName, weight, createDT, nextFetchDT) VALUES ('java.com', 1, now(), now());
INSERT INTO websites (domainName, weight, createDT, nextFetchDT) VALUES ('php.net', 1, now(), now());
INSERT INTO websites (domainName, weight, createDT, nextFetchDT) VALUES ('python.org', 1, now(), now());

爬取顺序

下面福哥给出一个爬取网站的websites数据表的查询SQL语句,使用这个语句可以让每个域名都不会被冷落,让每个域名都有被爬取的机会。

SELECT * FROM websites ORDER BY nextFetchDT ASC, lastFetchDT DESC;

爬取内容

下面福哥来说说爬取网站时候需要爬取哪些内容?这个需要详细的说一说,它不仅仅有先后顺序,还有关联性,如果没有想明白的话,就会弄的乱七八糟的。

首页

一个网站一定会有一个首页,网站首页一般情况下都是www前缀的,所以如果域名没有二级前缀的话,我们就可以自动在前面加上一个www前缀。

网站除了www开头的这种正式网站首页域名外,还会有一些功能性的其他域名作为网站的首页的域名,这种网站一般是一个大型的平台的子网站,例如:tieba.baidu.com、im.qq.com等等。

子页

爬取完网站首页之后就可以通过超链接标签进行二级页面的扫描操作,扫描到的二级页面进行爬取后又可以扫描三级页面,以此类推就可以将一个网站的全部网页爬取出来了。

但是有些网站的页面数量特别多,搜索引擎一般会先轻量地爬取一些页面,看看用户对这些页面的“兴趣”,从而判断这个网站的“价值”,如果“价值”高则增加爬取页面的数量,否则就减少爬取页面的数量。

编码

网页的编码决定了爬取到的网页内容的读取方式,如果网页的编码不是UTF-8的话,那么我们拿到之后还需要将它转换成UTF-8才行,转换的过程中就需要知道网页的原始编码。

如果不进行编码的修正处理,那么搜索引擎就会匹配不到,用户也就无法正常使用了。

da9a90f09e1ad04c.jpg

文字内容

可以看到网页上是由一个个的html标签和文字组成的,文字内容是有价值的,但是html标签内容用户是不关心的。所以,我们要将网页内容的body部分取出来,然后再去掉所有html标签,还要去掉所有script标签以及style标签,最后剩下的才是用户想看的内容。

编程

遍历websites

首先通过查询websites数据表,对每个域名进行爬取任务处理,并根据weight权重值对域名的爬取力度和收录量进行一定控制。

爬取域名

使用前面教给大家的selenium软件包,对域名对应的网页进行爬取,拿到页面内容后再遍历里面的超链接标签,再打开这些超链接进行子级页面的爬取,直到全部爬取完成或者达到我们预计的爬取量为止。

保存页面内容

将爬取到的网页内容,经过解析得到编码、标题、关键字、描述等等关键信息,以及纯文字的网页内容,将它们保存到webpages数据表和webpage_data数据表当中。

保存新域名

在爬取子级页面的时候,如果发现了和域名不一样的域名,将域名提取出来保存到websites表里,以供将来进行爬取使用。

总结

今天我们了解了搜索引擎的蜘蛛爬取的相关知识,大家下去可以自己来编写网页蜘蛛的程序。

福哥在这里说明一下,在后面的课程当中福哥会讲解编程的分析思路,注意要点,以及一些关键的代码,但是不会给出完全的编程代码。这也是为了给大家动脑筋的机会,如果完完全全按照福哥的代码复制粘贴起来,那样是无法学会编程的。因此,希望大家可以主动考虑,自己编写代码进行尝试,在一次次的失败当中积累经验,寻找正确的方法去编写出自己的程序。

好了,童鞋们,加油吧!