scrapy-redis所有request爬取完毕,如何解决爬虫空跑问题?

scrapy-redis所有request爬取完毕,如何解决爬虫空跑问题?

1. 背景

这里写图片描述
根据scrapy-redis分布式爬虫的原理,多台爬虫主机共享一个爬取队列。当爬取队列中存在request时,爬虫就会取出request进行爬取,如果爬取队列中不存在request时,爬虫就会处于等待状态,行如下:

E:\Miniconda\python.exe E:/PyCharmCode/redisClawerSlaver/redisClawerSlaver/spiders/main.py
2017-12-12 15:54:18 [scrapy.utils.log] INFO: Scrapy 1.4.0 started (bot: scrapybot)
2017-12-12 15:54:18 [scrapy.utils.log] INFO: Overridden settings: {'SPIDER_LOADER_WARN_ONLY': True}
2017-12-12 15:54:18 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
 'scrapy.extensions.telnet.TelnetConsole',
 'scrapy.extensions.logstats.LogStats']
2017-12-12 15:54:18 [myspider_redis] INFO: Reading start URLs from redis key 'myspider:start_urls' (batch size: 110, encoding: utf-8
2017-12-12 15:54:18 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'redisClawerSlaver.middlewares.ProxiesMiddleware',
 'redisClawerSlaver.middlewares.HeadersMiddleware',
 'scrapy.downloadermiddlewares.retry.RetryMiddleware',
 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware',
 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2017-12-12 15:54:18 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
 'scrapy.spidermiddlewares.referer.RefererMiddleware',
 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2017-12-12 15:54:18 [scrapy.middleware] INFO: Enabled item pipelines:
['redisClawerSlaver.pipelines.ExamplePipeline',
 'scrapy_redis.pipelines.RedisPipeline']
2017-12-12 15:54:18 [scrapy.core.engine] INFO: Spider opened
2017-12-12 15:54:18 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2017-12-12 15:55:18 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2017-12-12 15:56:18 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)

  •  
  • 可是,如果所有的request都已经爬取完毕了呢?这件事爬虫程序是不知道的,它无法区分结束和空窗期状态的不同,所以会一直处于上面的那种等待状态,也就是我们说的空跑。
  • 那有没有办法让爬虫区分这种情况,自动结束呢?

2. 环境

  • 系统:win7
  • scrapy-redis
  • redis 3.0.5
  • python 3.6.1

3. 解决方案

  • 从背景介绍来看,基于scrapy-redis分布式爬虫的原理,爬虫结束是一个很模糊的概念,在爬虫爬取过程中,爬取队列是一个不断动态变化的过程,随着request的爬取,又会有新的request进入爬取队列。进进出出。爬取速度高于填充速度,就会有队列空窗期(爬取队列中,某一段时间会出现没有request的情况),爬取速度低于填充速度,就不会出现空窗期。所以对于爬虫结束这件事来说,只能模糊定义,没有一个精确的标准。
  • 所以,下面这两种方案都是一种大概的思路。

3.1. 利用scrapy的关闭spider扩展功能


 
 
  1. # 关闭spider扩展
  2. class scrapy.contrib.closespider.CloseSpider
  3. 当某些状况发生,spider会自动关闭。每种情况使用指定的关闭原因。
  4. 关闭spider的情况可以通过下面的设置项配置:
  5. CLOSESPIDER_TIMEOUT
  6. CLOSESPIDER_ITEMCOUNT
  7. CLOSESPIDER_PAGECOUNT
  8. CLOSESPIDER_ERRORCOUNT

  •  
  • CLOSESPIDER_TIMEOUT

 
 
  1. CLOSESPIDER_TIMEOUT
  2. 默认值: 0
  3. 一个整数值,单位为秒。如果一个spider在指定的秒数后仍在运行, 它将以 closespider_timeout 的原因被自动关闭。 如果值设置为 0(或者没有设置),spiders不会因为超时而关闭。

  •  
  • CLOSESPIDER_ITEMCOUNT

 
 
  1. CLOSESPIDER_ITEMCOUNT
  2. 缺省值: 0
  3. 一个整数值,指定条目的个数。如果spider爬取条目数超过了指定的数, 并且这些条目通过item pipeline传递,spider将会以 closespider_itemcount 的原因被自动关闭。

  •  
  • CLOSESPIDER_PAGECOUNT

 
 
  1. CLOSESPIDER_PAGECOUNT
  2. 0 .11 新版功能.
  3. 缺省值: 0
  4. 一个整数值,指定最大的抓取响应( reponses)数。 如果 spider抓取数超过指定的值,则会以 closespider_pagecount 的原因自动关闭。 如果设置为0(或者未设置), spiders不会因为抓取的响应数而关闭。

  •  
  • CLOSESPIDER_ERRORCOUNT

 
 
  1. CLOSESPIDER_ERRORCOUNT
  2. 0 .11 新版功能.
  3. 缺省值: 0
  4. 一个整数值,指定 spider可以接受的最大错误数。 如果 spider生成多于该数目的错误,它将以 closespider_errorcount 的原因关闭。 如果设置为0(或者未设置), spiders不会因为发生错误过多而关闭。

  •  
  • 示例:打开 settings.py,添加一个配置项,如下

 
 
  1. # 爬虫运行超过23.5小时,如果爬虫还没有结束,则自动关闭
  2. CLOSESPIDER_TIMEOUT = 84600

  •  
  • 特别注意:如果爬虫在规定时限没有把request全部爬取完毕,此时强行停止的话,爬取队列中就还会存有部分request请求。那么爬虫下次开始爬取时,一定要记得在master端对爬取队列进行清空操作。
  • 另外如果是分布式爬虫,先确认几台机器同时跑,拿CLOSESPIDER_ITEMCOUNT来说,比如要拿100条数据,10台机器一起跑,那么CLOSESPIDER_ITEMCOUNT=10即可

 

第二种方案:改scrapy_redis的源码,不适合分布式部署

            </div>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值