Scrapy Request方法的meta-args是浅表副本,但是Request方法的meta-args是scrapy_redis中的深表副本。为什么?

时间:2018-08-17 13:54:23

标签: scrapy

草率:

import scrapy
from  scrapy.spider import Request

class TestspiderSpider(scrapy.Spider):
    name = 'testspider'
    allowed_domains = ['mzitu.com']
    start_urls = ['http://www.mzitu.com/']

    def start_requests(self):
        L =[]
        print("L-id:",id(L),"first")
        yield Request(url="http://www.mzitu.com/5675",callback=self.parse,meta={"L":L},dont_filter=True)
    def parse(self, response):
        L = response.meta.get('L')
        print("L-id:", id(L),"second")

输出:

  

L-id:2769118042568首先

     

L-id:2769118042568秒

     

它们相等

     

这是浅表副本

scrapy_redis

from scrapy_redis.spiders import RedisSpider
from scrapy.spider import Request

class MzituSpider(RedisSpider):   #scrapy_redis
    name = 'mzitu'
    redis_key = 'a:a'             #this is discard
    def start_requests(self):     #Because Rewrite the method of RedisSpider
        L =[]
        print("L-id:",id(L),"first")
        yield Request(url="http://www.mzitu.com/5675",callback=self.parse,meta={"L":L},dont_filter=True)
    def parse(self, response):
        L = response.meta.get('L')
        print("L-id:", id(L),"second")

输出:

  

L-id:1338852857992

     

第一个L-id:1338852858312第二个

     

他们不相等

     

这是深层副本

问题:

  

我想知道为什么吗?

     

我该如何解决?

     

让scrapy_redis更改为浅表副本

1 个答案:

答案 0 :(得分:1)

这与以下事实有关:scrapy-redis使用其自己的调度程序类,该类通过redis对所有请求进行序列化/反序列化,然后再将它们推送到下载器(它在redis上保持队列)。基本上,scrapy-redis是核心功能,因此没有“简便”的解决方法。我的建议是不要将太多对运行时敏感的东西放到meta中,因为这通常不是最好的想法。