当前位置:嗨网首页>书籍在线阅读

11-抓取结果

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

[toc]

2.7 抓取结果

现在,我们已经完成所有爬虫代码的实现,接下来将通过如下代码片段,测试这3种方法的相对性能。代码中的导入操作期望你的目录结构与本书代码库相同,因此请根据需要进行调整。

import time
import re
from chp2.all_scrapers import re_scraper, bs_scraper,
    lxml_scraper, lxml_xpath_scraper
from chp1.advanced_link_crawler import download
NUM_ITERATIONS = 1000 # number of times to test each scraper
html =
download('http://example.python-scraping.com/places/view/United-Kingdom-239')
scrapers = [
    ('Regular expressions', re_scraper),
     ('BeautifulSoup', bs_scraper),
     ('Lxml', lxml_scraper),
     ('Xpath', lxml_xpath_scraper)]
for name, scraper in scrapers:
    # record start time of scrape
    start = time.time()
    for i in range(NUM_ITERATIONS):
        if scraper == re_scraper:
            re.purge()
        result = scraper(html)
        # check scraped result is as expected
        assert result['area'] == '244,820 square kilometres'
# record end time of scrape and output the total
end = time.time()
print('%s: %.2f seconds' % (name, end - start))

在这段代码中,每个爬虫都会执行1000次,每次执行都会检查抓取结果是否正确,然后打印总用时。这里使用的 download 函数依然是上一章中定义的那个函数。请注意,我们在代码行中调用了 re.purge() 方法。默认情况下,正则表达式模块会缓存搜索结果,为了使其与其他爬虫的对比更加公平,我们需要使用该方法清除缓存。

下面是在我的计算机中运行该脚本的结果。

$ python chp2/test_scrapers.py
Regular expressions: 1.80 seconds
BeautifulSoup: 14.05 seconds
Lxml: 3.08 seconds
Xpath: 1.07 seconds

由于硬件条件的区别,不同计算机的执行结果也会存在一定差异。不过,每种方法之间的相对差异应当是相似的。从结果中可以看出,在抓取我们的示例网页时,Beautiful Soup的速度是其他方法的1/6。实际上这一结果是符合预期的,因为 lxml 和正则表达式模块都是C语言编写的,而 BeautifulSoup 则是纯Python编写的。一个有趣的事实是, lxml 表现得和正则表达式差不多好。由于 lxml 在搜索元素之前,必须将输入解析为内部格式,因此会产生额外的开销。而当抓取同一网页的多个特征时,这种初始化解析产生的开销就会降低, lxml 也就更具竞争力。正如我们在使用XPath解析器时所看到的, lxml 也可以直接使用正则表达式与之抗争。这真是一个令人惊叹的模块!

虽然我们强烈鼓励你使用 `lxml` 进行解析,不过网络抓取的最大性能瓶颈通常是网络。我们将会讨论并行工作流的方法,从而让你能够通过并行处理多个请求工作,来提升爬虫的速度。