网页爬虫程序开发经验谈(转)

现在是网络的时代,所有数据都可以在互联网上得到,所以能够自动抓取Web数据的网页爬虫程序(又叫网络机器人,Web Robot)就逐渐流行了起来。

开发网页爬虫的过程,需要运用各种Heuristic(摸索体验)的作法:尝试你的想法,修正预期以外的错误(错误通常相当多),一再重复进行,直到网页爬虫可行为止。所以写网页爬虫程序时,是需要一点点耐心的。

一般的状况下,网页爬虫程序会先取一个网页,从此网页取出所有“后续的链接”,然后继续取这些链接的网页。网页的组织方式如果是线性的(例如:每个网页都有“前一笔资料”与“下一笔数据”的超级链接),那么超级链接就不会重复,所以就不需要判断这些链接有无重复。但组织方式只要不是线性的,都需要判断网页超级链接有无重复。

你以为HTTP状态码(status code)是代表正常的200,就表示能够顺利取网页吗?那可不一定,我发现有些服务器会限制同时上线的最大联机数目,超出限制,就会送出“服务器忙碌中”的HTML内容,但HTTP状态码(status code)居然还是使用代表正常的200。会不会遇到这种状况?何时会遇到?很难说得准。如果你想预防这种问题,可以从判断取内容的checksum有无重复来下手。

为了防堵网页爬虫,有些网站会限制来自同一个IP的请求频率。当频率超过限制,就会对此IP联机请求进行屏蔽,客户端最后会Timeout,联机失败。所以,当你遇到联机失败的状况,请先更换成新的IP,以确定服务器是否真的挂了,或者只是你的IP被封锁了。如果确定IP被封锁,你可以采用两种策略:(1)随时动态更换IP;或者(2)调节网页爬虫的请求频率。

如果你的计算机上同时有两三个IP,你当然可以在这些IP之间轮替更换,但这样其实帮助不大,因为IP被封锁通常会维持好一段时间,轮完第三个IP之后,恐怕第一个IP也还没被服务器从黑名单中去除。如果你要动态更换IP,最好改用ADSL拨号网络,因为ISP拥有大量的IP,会分配到和之前相同的IP机率很低。一旦你发现目前的IP被封锁,便可以立刻呼叫相关的API将网络断线并重新拨号,取得新的IP继续执行。

如果你不知道该如何呼叫拨号API,或者根本没有拨号网络,那么你只好降低网页爬虫发出请求的频率。频率太低,取得数据的速度太慢;频率太高,很快就会被服务器封锁。如何调整出一个理想值,通常需要测试好一阵子。

对网页资料的加工处理方式,通常是先将超级链接更新到本地文件,再提取重要数据保存到其他地方。更新超级链接其实满容易的,不容易出错,但“提取重要数据”就可能会遇到相当多问题,值得进一步探讨。

通过网页爬虫程序取的网页数据,通常需要经过加工处理。因此建议你不要一边取网页,一边加工处理,最好等网页全部取之后,再进行数据提取。为了避免URL名称不适合用来当成档名(例如Windows中不能用“con”当文件名),我习惯使用数字序号当文件名,然后再建立一个URL和数字序号的对照表(可以加上超级链接,以方便取用)。

在提取数据前,你需要先花一点时间研究出这些网页的HTML模板,接着你就可以取出特定tag的element,或者“以特定字符串为识别”的数据。我的经验是,光看几个HTML内容,仍不足以推测出完整的模板,有些状况可能是一百个或一千个网页才发生一次(更不用说还有一些是网站本身建构时的疏失)。因此,最好能先写一个程序扫描所有取的网页,证实你构想中的HTML模板是正确的,然后才开始进行数据提取。

在研究网页模板时,如果发现网页内出现JavaScript,你应该判断是否可以对它置之不理。因为许多网页的JavaScript程序代码是用来处理网页互动,和我们所关心的网页内容无关,可以不予理会。但如果遇到和数据相关的JavaScript程序代码(会产生HTTP请求),就必须特别注意。

你可以动用外部的JavaScript Engine(例如Rhino)来处理JavaScript程序代码,但是对网页爬虫程序来说,大多数的时候,其实没有必要这么做。你可以先阅读理解这些 JavaScript程序代码,知道这段程序的目的是发出什么HTTP请求,就可以让网页爬虫自行模拟这样的HTTP请求。

当你的计算机跑着网页爬虫程序时,只要有预期以外的事情发生(例如格式不对、网站不通),就需要人的介入。尤其前几个小时是重要的观察期,这个时候最好乖乖地坐在计算机前,当出状况时,网页爬虫可以发出声音提醒我们进行处理。

我一直觉得,开发网页爬虫是相当实用、有趣、需要技巧的,且网页爬虫程序通常不大,所以很适合当作“下班后的自我挑战”,或是老师留给学生当作业。如果你没写过网页爬虫程序,我建议你马上试试看。

 
原文地址 http://blog.163.com/biaozongchen/blog/static/135986820096792113283/ 


猜你喜欢

转载自solidfish.iteye.com/blog/746475