先给结果:重写make_requests_from_url方法!!
如果想知道原因,请继续往下看
scrapy_redis
是做分布式爬虫的时候经常会用到的一个爬虫框架,scrapy_redis
框架是基于scrapy框架,提供了一些以redis
为基础的组件。
相对于scrapy
设置的start_urls
,在scrapy_redis
中只需要设置redis_key
就可以了,爬虫会自动去redis
的相应的key中取到url,然后包装成Request
对象,保存在redis的待爬取队列(request queue)中。
但是我们有时候可能想自定义url请求,比如我们可能想要初始化的请求是个post
而不是get
,或者由于某些原因导致我们从redis
中取出来的数据并不是可以直接请求的url。这些都需要我们对redis
中的url做进一步的处理,这里主要通过对scrapy_redis
中的RedisSpider
类进行分析,看看怎样修改才能达到目的。
我们自己实现的spider类基本上通过继承RedisSpider来完成任务调度的。首先我们看看RedisSpider类的源码:
class RedisSpider(RedisMixin, Spider):
@classmethod
def from_crawler(self, crawler, *args, **kwargs):
obj = super(RedisSpider, self).from_crawler(crawler, *args, **kwargs)
obj.setup_redis(crawler)
return obj
不难看出RedisSpider
类继承自scrapy_redis.spiders.RedisMixin
类和scrapy.spiders.Spider
类,这里使用了多继承,并用RedisMixin
调度功能覆盖Spider
原生的调度功能。
RedisMixin
类主要包括六个方法:
- start_requests
- setup_redis
- next_requests
- make_request_from_data
- schedule_next_requests
- spider_idle
那这些方法都有什么作用呢?我们注意到,RedisSpider
类在实例化之后,调用了setup_redis
方法,该方法源码如下:
def setup_redis(self, crawler=None):
"""Setup redis connection and idle signal.
This should be called after the spider has set its crawler object.
"""
if self.server is not None:
return
if crawler is None:
# We allow optional crawler argument to keep backwards