1
zdnyp 2020-07-08 17:49:15 +08:00
写一个 pipeline 的基类,在 open_spider 的时候连接,close_spider 的时候关闭
|
2
a65420321a OP @zdnyp
from .settings import ITEM_KEY import json, redis class RedisPipeline: def __init__(self, redis_host, redis_port, redis_db): self.redis_host = redis_host self.redis_port = redis_port self.redis_db = redis_db @classmethod def from_crawler(cls, crawler): return cls( redis_host=crawler.settings.get('REDIS_HOST'), redis_port=crawler.settings.get('REDIS_PORT'), redis_db=crawler.settings.get('REDIS_DB') ) def open_spider(self, spider): self.pool = redis.ConnectionPool(host=self.redis_host, port=self.redis_port, db=self.redis_db) self.conn = redis.StrictRedis(connection_pool=self.pool) print('#### pipelines.open_spider') def close_spider(self, spider): pass def process_item(self, item, spider): self.conn.rpush(ITEM_KEY, json.dumps(item)) return item 这样没错吧? 我没搞懂的是,在 middleware 和 spider 里面要怎么调用这个 self.conn 呢? |
3
996635 2020-07-08 19:47:03 +08:00
建议楼主看一下 scrapy 自带的几个 extensions 例子, 可能会有一些灵感. 印象中 scrapy 准备的几个钩子可以做这个事情.
另外,如果想全局复用连接池, 要考虑线程安全的问题. spider 之间传递上下文靠 meta. pipeline 里可以获取 spider 的对象. |
4
a65420321a OP @996635
额,你说的钩子指的是哪些? 数据库链接搞定了 在 spider 下__init__构建了 self.pool 和 self.conn 然后在 pipeline 里通过 process_item 中的 spider 参数调用 spider.conn 可以复用数据库链接 middleware 同样是通过 process_request 的 spider 参数 话说,为啥我搜出来的都是说在 pipeline 下的 open_spider 里创建数据库链接,这样的话别的地方通过什么方式调用呢? |
5
Kobayashi 2020-07-09 12:58:22 +08:00 via Android
@zdnyp 搭车问一下。我目前也是基类,每个 pipeline 绑定一个 Redis connection 。不过不太明白 itempipeline 工作原理,itempipeline 支持并行还是并发,pipeline 上单一 Redis 连接后用吗,要必要开连接池?
另外实际上 Redis 连接也能绑在 spider 上。spider 应该只有一个实例,异步的话是不是需要 redis 连接池? Redis 连接到底跟着谁比较好。 scrapy 文档里 architecture 解释的太简单了。 |
6
Kobayashi 2020-07-09 13:06:35 +08:00
|
7
Kobayashi 2020-07-09 13:10:10 +08:00
我的思路是
1. 每个 Pipeline 一个 redis 连接。由于不明白 pipeline 工作原理(并发?并行?),不确定要不要开连接池。 2. pipeline 上没有 redis 连接。直接绑在 Spider 上, Pipeline.process(self,item,spider) 可以访问到 spider 上的 redis 连接。这个恐怕需要连接池,大小不知道设置多少合适。 |
8
a65420321a OP @Kobayashi
我之前一直在纠结,怎么在 spider 里面直接调用 pipeline 的 redis 链接,没有相通,最后我是在 spider 里面声明了 redis 连接池,在 pipeline 和 middleware 通过 spider 参数直接调用 redis 链接 现在看下来,在 pipeline 的 open_spider 中声明 redis 链接,在 spider 里面把需要筛选的东西处理成不同的 item,通过 pipeline 的 process_item 调用 redis 链接。。 我没理解错吧? 可是,如果这样的话,我需要在 middleware 里使用代理,也要用到 redis,这又要怎么搞。。。 |
9
Kobayashi 2020-07-09 21:44:09 +08:00
@a65420321a 按照我定义 RedisPipeline 类的方法再定义一个 ProxyPipeline 基类。自己创建的 MyPipeline 同时继承这 2 个类即可。我自己使用方式是在 Pipeline 中同时使用 redis 和 database 连接。
|
10
a65420321a OP @Kobayashi
。。。pipeline 里面可以给 request 加代理吗? |
11
Kobayashi 2020-07-11 01:14:38 +08:00 via Android
@a65420321a pipeline 只能拿到 Item,也就是你从结果中拿到的数据。加代理要在请求被 downloader 处理前,自定义 downloader middleware 即可。
兄弟,翻翻教程和文档好吗?教程的话推荐《 Python 3 爬虫开发实战》的最后几张 scrapy 讲解,介绍了 scrapy 架构。重要的是带了很多可以生产直接使用的实例。之后读完文档就可以随意用了。 |
12
a65420321a OP @Kobayashi
看过的~你们说 pipeline 让我以为 middleware 可以调 pipeline 来着。。。 |