scrapy -redis分布式爬虫

settings 配置文件:


# 使用scrapy-redis里的去重组件,不使用scrapy默认的去重方式
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis里的调度器组件,不使用默认的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 允许暂停,redis请求记录不丢失
SCHEDULER_PERSIST = True
# 默认的scrapy-redis请求队列形式(按优先级)
SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderPriorityQueue"
# 队列形式,请求先进先出
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderQueue"
# 栈形式,请求先进后出
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderStack"

# 只是将数据放到redis数据库,不需要写pipelines文件
ITEM_PIPELINES = {
#    'Sina.pipelines.SinaPipeline': 300,
    'scrapy_redis.pipelines.RedisPipeline': 400,
}

# LOG_LEVEL = 'DEBUG'

# Introduce an artifical delay to make use of parallelism. to speed up the
# crawl.
DOWNLOAD_DELAY = 1
# 指定数据库的主机IP
REDIS_HOST = "172.0.0.1"
# 指定数据库的端口号
REDIS_PORT = 6379
# redis 密码
REDIS_PARAMS  = {
 'password': **********,
}

spiders.py

不在使用scrapy原有的Spider类,重写的RedisSpider继承了Spider和RedisMixin这两个类,RedisMixin是用来从redis读取url的类。当我们生成一个Spider继承RedisSpider时,调用setup_redis函数,这个函数会去连接redis数据库

指定  redis_key = ' '  替代start_urls  我们将在 redis 中push 起始url

这里我们要注意下,scrapy 起始请求调用 start_requests 方法 回调parse方法。如果我们重写了这个方法,而且改变了start_urls名字,会出现问题,我们大可不必这样, 可以在parse里面进行数据的处理或者新的url请求,然后回调其他函数parse_item或者其他,

from scrapy_redis.spiders import RedisSpider

class ToutiaoSpider(RedisSpider):
    name = 'toutiao'
    allowed_domains = ['toutiao.com']
    redis_key = 'toutiao:start_urls'
    # start_urls = ['http://open.toutiao.com/?']
    def parse(self, response):
        pass
        xxxx

    def parse_item():
        pass
        xxxx

启动爬虫 >>>>> 使用本地redis数据库

 

此时爬虫处于等待命令状态 

我们在redis lpush起始url(可以写shell脚本去在启动爬虫的时候master端去push url )

127.0.0.1:6379> lpush toutiao:start_urls http://open.toutiao.com/?

lpush完成后 爬虫开工作 

这里要注意的是在多个 爬虫运行时候,当一个爬虫url爬取完毕,爬虫会出现空跑问题,

我们可以修改scrapy-redis 源文件里面的,这里有两种修改方式

参考这里

# schedluer.py
    def next_request(self):
        block_pop_timeout = self.idle_before_close
        request = self.queue.pop(block_pop_timeout)
        if request and self.stats:
            self.stats.inc_value('scheduler/dequeued/redis', spider=self.spider)
        if request is None:
            self.spider.crawler.engine.close_spider(self.spider, 'queue is empty')
        return request
# 当然也可以在scrapy_redis中spiders.py模块 
    def next_requests(self):
        """Returns a request to be scheduled or none."""
        use_set = self.settings.getbool('REDIS_START_URLS_AS_SET', defaults.START_URLS_AS_SET)
        fetch_one = self.server.spop if use_set else self.server.lpop
        # XXX: Do we need to use a timeout here?
        found = 0
        # TODO: Use redis pipeline execution.
        while found < self.redis_batch_size:
            data = fetch_one(self.redis_key)
            if not data:
                # Queue empty.
                print('+++++queue is empty')
                self.crawler.engine.close_spider(self.spider, 'queue is empty')
                break
            req = self.make_request_from_data(data)
            if req:
                yield req
                found += 1
            else:
                self.logger.debug("Request not made from data: %r", data)

        if found:
            self.logger.debug("Read %s requests from '%s'", found, self.redis_key)

参考: https://segmentfault.com/a/1190000014333162?utm_source=channel-hottest

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值