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

09-中断与恢复爬虫

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

[toc]

8.4.2 中断与恢复爬虫

在抓取网站时,暂停爬虫并于稍后恢复而不是重新开始,有时会很有用。比如,软件更新后重启计算机,或是要爬取的网站出现错误需要稍后继续爬取时,都可能会中断爬虫。

非常方便的是,Scrapy内置了对暂停与恢复爬取的支持,这样我们就不需要再修改示例爬虫了。要开启该功能,我们只需定义用于保存爬虫当前状态目录的 JOBDIR 设置即可。需要注意的是,多个爬虫的状态需要保存在不同的目录当中。

下面是在我们的爬虫中使用该功能的示例。

$ scrapy crawl country_or_district -s LOG_LEVEL=DEBUG -s
JOBDIR=../../../data/crawls/country_or_district
...
2017-03-24 13:41:54 [scrapy.core.engine] DEBUG: Crawled (200) <GET
http://example.python-scraping.com/view/Anguilla-8> (referer:
http://example.python-scraping.com/)
2017-03-24 13:41:54 [scrapy.core.scraper] DEBUG: Scraped from <200
http://example.python-scraping.com/view/Anguilla-8>
{'name': ['Anguilla'], 'population': ['13,254']}
2017-03-24 13:41:59 [scrapy.core.engine] DEBUG: Crawled (200) <GET
http://example.python-scraping.com/view/Angola-7> (referer:
http://example.python-scraping.com/)
2017-03-24 13:41:59 [scrapy.core.scraper] DEBUG: Scraped from <200
http://example.python-scraping.com/view/Angola-7>
{'name': ['Angola'], 'population': ['13,068,161']}
2017-03-24 13:42:04 [scrapy.core.engine] DEBUG: Crawled (200) <GET
http://example.python-scraping.com/view/Andorra-6> (referer:
http://example.python-scraping.com/)
2017-03-24 13:42:04 [scrapy.core.scraper] DEBUG: Scraped from <200
http://example.python-scraping.com/view/Andorra-6>
{'name': ['Andorra'], 'population': ['84,000']}
^C2017-03-24 13:42:10 [scrapy.crawler] INFO: Received SIG_SETMASK, shutting
down gracefully. Send again to force
...
[country] INFO: Spider closed (shutdown)

在上面的执行过程中,我们看到行中出现了一个 ^C ,表示 Received SIG_SETMASK ,这和本章前面用于停止抓取的Ctrl + C或cmd + C是相同的。想要Scrapy保存爬虫状态,就必须等待它正常结束,而不能经受不住诱惑再次按下终止键强行立即关闭!现在,爬虫状态保存在 crawls/country_or_districtdata 目录中。如果我们查看该目录的话,可以在其中看到保存的文件(请注意,对于Windows用户来说,下面的命令及目录语法需要改变)。

$ ls ../../../data/crawls/country_or_district/
requests.queue requests.seen spider.state

通过运行相同的命令,可以恢复爬取。

$ scrapy crawl country_or_district -s LOG_LEVEL=DEBUG -s
JOBDIR=../../../data/crawls/country_or_district
...
2017-03-24 13:49:49 [scrapy.core.engine] INFO: Spider opened
2017-03-24 13:49:49 [scrapy.core.scheduler] INFO: Resuming crawl (13
requests scheduled)
2017-03-24 13:49:49 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at
0 pages/min), scraped 0 items (at 0 items/min)
2017-03-24 13:49:49 [scrapy.extensions.telnet] DEBUG: Telnet console
listening on 127.0.0.1:6023
2017-03-24 13:49:49 [scrapy.core.engine] DEBUG: Crawled (200) <GET
http://example.python-scraping.com/robots.txt> (referer: None)
2017-03-24 13:49:54 [scrapy.core.engine] DEBUG: Crawled (200) <GET
http://example.python-scraping.com/view/Cameroon-40> (referer:
http://example.python-scraping.com/index/3)
2017-03-24 13:49:54 [scrapy.core.scraper] DEBUG: Scraped from <200
http://example.python-scraping.com/view/Cameroon-40>
{'name': ['Cameroon'], 'population': ['19,294,149']}
...

此时,爬虫从刚才暂停的地方恢复运行,和正常启动一样继续进行爬取。该功能对于我们的示例网站而言用处不大,因为要下载的页面数量是可控的。不过,对于那些需要爬取几个月的大型网站而言,能够暂停和恢复爬虫就非常方便了。

有一些边界情况在这里没有覆盖,可能会在恢复爬取时产生问题,比如cookie和会话过期等。此类问题可以从Scrapy的官方文档中进行详细了解,其网址为 `http://doc.scrapy.org/en/latest/topics/jobs.html` 。

Scrapy性能调优

如果我们检测示例网站的初始完整抓取,记录开始和结束时间的话,会发现该抓取过程花费了大约1,697秒的时间。如果我们计算每个页面(平均)多少秒的话,会得到每个页面大约花费了6秒的时间。已知我们没有使用Scrapy的并发功能,以及我们在两次请求之间添加了5秒的延时,也就意味着Scrapy解析以及抽取数据的时间大约在每个页面1秒左右(请回顾第2章中的内容,我们使用XPath的最快抓取是1.07s)。本书作者之一Richard Lawson在PyCon 2014的演讲中对比了不同网络爬虫库的速度,即便如此,Scrapy仍然比我能找到的任何其他爬虫库都快得多。我编写过一个简单的Google搜索爬虫,每秒返回(平均)100个请求。从那之后,Scrapy又经过了很长的一段路,我也总是推荐它作为性能最好的Python爬虫框架。

除了利用Scrapy使用的并发性(通过Twisted)以外,Scrapy还可以使用类似页面缓存以及其他性能注意事项(比如利用代理以允许针对同一站点的更多并发请求)进行调优。为了安装缓存,你应该首先阅读缓存中间件的文档( https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#module-scrapy.downloadermiddlewares.httpcache )。你可能已经在 settings.py 文件中见到过几个很好的实现正确缓存设置的例子。对于实现代理来说,也有一些很有帮助的库(因为Scrapy只能访问简单的中间件类)。当前最流行的库是 scrapy-proxies ,其地址为 https://github.com/aivarsk/scrapy-proxies ,它已经支持Python 3,并且很容易整合。

和往常一样,库和推荐的设置可能会改变,因此阅读最新的Scrapy文档应该始终是你检测性能以及变更爬虫的第一站。