20.3 高级Web客户端

Web浏览器是基本的Web客户端,主要用来在Web上查询或者下载文件。而Web的高级客户端并不只是从因特网上下载文档。

高级Web客户端的一个例子就是网络爬虫(也称蜘蛛或机器人)。这些程序可以基于不同目的在因特网上探索和下载页面,其中包括:

  • 为Google和Yahoo这类大型的搜索引擎建索引;

  • 脱机浏览——将文档下载到本地,重新设定超链接,为本地浏览器创建镜像;

  • 下载并保存历史记录或框架;

  • Web页的缓存,节省再次访问Web站点的下载时间。

我们下边介绍网络爬虫crawl.py,抓取Web的开始页面地址(URL),下载该页面和其他后续链接页面,但是仅限于那些与开始页面有着相同域名的页面。如果没有这个限制的话,你的硬盘将会被耗尽!crwal.py的代码在例20.2中展示。

逐行(逐个类)解释

1 ~ 11行

该脚本的开始部分包括Python在Unix上标准的初始化行和一些模块属性的导入,它们都会在本应用程序中用到。

13 ~ 49行

Retriever类的责任是从Web下载页面,解析每个文档中的链接并在必要的时候把它们加入“to-do”队列。我们为每个从网上下载的页面都创建一个Retriever类的实例。Retriever中的方法展现了它的功能:构造器(init())、filename()、 download()和parseAndGetLinks().

filename()方法使用给定的URL找出安全、有效的相关文件名并存储在本地。大体上说,它会去掉URL的“http://”前缀,使用剩余的部分作为文件名,并创建必要的文件夹路径。那些没有文件名前缀的URL则会被赋予一个默认的文件名“index. htm”(可以在调用filename()时重新指定这个名字).

构造器实例化了一个Retriever对象,并把URL和通过filename()获得的相应文件名都作为本地属性保存起来。

例20.2 高级Web客户端:网络爬虫(crawl.py)

这个爬虫程序包括两个类,一个管理整个crawling进程(Crawler),一个检索并解析每一个下载的Web页面(Retriever).

20.3 高级Web客户端 - 图1

20.3 高级Web客户端 - 图2

20.3 高级Web客户端 - 图3

20.3 高级Web客户端 - 图4

正如你想象的,download()方法实际会连上网络去下载给定链接的页面。它使用URL调用urllib.urlretrieve()函数并把结果保存在filename中(该值由filename()返回)。如果下载成功,parse()方法会被调用来解析刚从网络拷贝下来的页面;否则会返回一个错误字符串。

如果Crawler判定没有错误发生,它会调用parseAndGetLinks()方法来解析新下载的页面并决定该页面中每个链接的后续动作。

51 ~ 98行

Crawler类是这次演示中的“明星”,掌管在一个Web站点上的整个抓爬过程。如果我们为应用程序添加线程,就可以为每个待抓爬的站点分别创建实例。Crawler的构造器在初始化过程中存储了三样东西,第一个是q,一个待下载链接的队列。这个队列在运行过程中会有涨落,有页面处理完毕它就变短,在下载的页面中发现新的链接则会让它变长。

Crawler包含的另两个数值是seen,一个所有“我们已看过”(已下载)的链接的列表和dom,我们把主链接的域名存储在这里,并用这个值来判定后续链接是否是该域的一部分。

Crawler还有一个静态数据成员count。这个计数器只是用来保存我们已经从网上下载的对象数目。每一个页面成功下载它就会增加。

除了构造器Crawler还有其他两个方法,getPage()和go(). go()只是简单地启动Crawler,它在代码的主体部分被调用。go()中有一个循环,只有队列中还有待下载的新链接它就会不停的执行。然而这个的真正工作者,却是getPage()方法。

getPage()初始化了一个Retriever对象,并把第一个链接赋给它然后让它执行。如果页面下载成功,计数器会增加并且链接会被加到“已看”列表。它会反复地检查每个已下载页面中的所有链接并判决是否有链接要被加入待下载队列。go()中的主循环会不停地推进处理过程直到队列为空,这时便大功告成。

属于其他域的链接、已经下载过的链接、已在队列中待处理的链接和“mailto: ”类型的链接在扩充队列时都会被忽略掉。

100 ~ 114行

main()是程序运行的起点,它在该脚本被直接调用时执行。其他导入crawl.py的模块则需要调用main()来启动处理过程。main()需要一个URL来启动处理,如果在命令行指定了一个(例如这个脚本被直接调用时),它就会使用这个指定的。否则,脚本进入交互模式,提示用户输入起始URL。一旦有了起始链接,Crawler就会被实例化并启动开来。

一个调用crawl.py的例子如下所示:

20.3 高级Web客户端 - 图5

20.3 高级Web客户端 - 图6

执行后,在本地的系统文件中将会在创建一个名为www.null.com的目录及子目录。左右的HTML文件都会显示在主目录下。