基于url构建request对象的方法
优采云 发布时间: 2021-08-18 21:15基于url构建request对象的方法
问题描述
默认情况下,RedisSpider启动时,会先读取redis中的spidername:start_urls,如果有值,则根据url构造请求对象。
例如:目标站点有一个接口,根据post请求参数返回结果。
那么,在这种情况下,构造请求的主要变换是请求体,API接口保持不变。
原来通过 URL 构建请求的策略不再适用。
所以,这个时候我们需要重写对应的方法。
重写方法
爬虫类需要继承自scrapy_redis.spiders.RedisSpider
开始请求
我需要从数据库中获取关键词数据,然后使用关键词构建请求。
这时候我们把关键词当作start_url,把关键词push添加到redis中
首先写一个方法将单个关键词push发送给redis
push_data_to_redis
def push_data_to_redis(self, data):
"""将数据push到redis"""
# 序列化,data可能是字典
data = pickle.dumps(data)
use_set = self.settings.getbool('REDIS_START_URLS_AS_SET', defaults.START_URLS_AS_SET)
self.server.spush(self.redis_key, data) if use_set else self.server.lpush(self.redis_key, data)
如果self.redis_key没有做任何声明,它会默认为spidername:start_urls
然后重写start_request
def start_requests(self):
if self.isproducer():
# get_keywords 从数据库读关键词的方法
items = self.get_keywords()
for item in items:
self.push_data_to_redis(item)
return super(DoubanBookMetaSpider, self).start_requests()
上面代码中有一个self.isproducer,这个方法是用来检测当前程序是否是producer,即提供关键词给redis
生产者
# (...)
def __init__(self, *args, **kwargs):
self.is_producer = kwargs.pop('producer', None)
super(DoubanBookMetaSpider, self).__init__()
def isproducer(self):
return self.is_producer is not None
# (...)
此方法需要配合scrapy命令行使用,例如:
// 启动一个生产者,producer的参数任意,只要填写了就是True
scrapy crawl myspider -a producer=1
// 启动一个消费者
scrapy crawl myspider
更多关于scrapy命令行的参数,参考文档:
make_request_from_data
在RedisMixin中查看make_request_from_data
方法注释信息:
从来自 Redis 的数据返回一个 Request 实例。
根据来自redis的数据返回一个Request对象
默认情况下,数据是经过编码的 URL。您可以覆盖此方法以
提供您自己的消息解码。
默认情况下,数据是经过编码的 URL 链接。您可以重写此方法以提供您自己的消息解码。
def make_request_from_data(self, data):
url = bytes_to_str(data, self.redis_encoding)
return self.make_requests_from_url(url)
将数据转换为字符串(网站link字符串),然后调用make_requests_from_url通过url构造请求对象
数据从哪里来?
查看RedisMixin的next_request方法
由此可知,数据是从redis中弹出的。之前我们序列化数据并push进去,现在我们pop出来,我们反序列化它并依赖它来构建请求对象
重写 make_request_from_data
def make_request_from_data(self, data):
data = pickle.loads(data, encoding=self.redis_encoding)
return self.make_request_from_book_info(data)
在这个例子中,构造请求对象的方法是self.make_request_from_book_info。在实际开发中,可以根据目标站的请求规则编写请求的构造方法。
最终效果
启动*敏*感*词*
scrapy crawl myspider -a producer=1
*敏*感*词*完成所有关键词push后,将转换为消费者并开始消费
在多个节点上启动消费者
scrapy crawl myspider
爬虫的开始总是基于现有数据采集新数据,例如基于列表页中的详情页链接采集detail页数据,基于关键词采集搜索结果, 等等。根据现有数据的不同,启动方式也不同,大体还是一样的。
本文文章由多人发布平台ArtiPub自动发布。