scrapy.Request.meta传递参数出现重复问题的解决方案

  一旦Spider的爬取的深度比较深时,数据的提取基本上是贯穿每一层的,为了将数据一层一层传递下去,我们需要将上一层提取的数据传递到下一层,供下一层使用,这时我们就需要使用的scrapy.Request的meta参数,其是一个字典。在传递不变数据时,不需要担心,但是我们传递的是一个Item类型或字典,这两者都属于可变类型,恰好又与scrapy的异步机制发生了碰撞,当我们将一个字典(或者Item)装进meta里面时,Item就会从Spider经过Engine最终到Pipeline,如果在这期间,Item被修改了,那么被Pipeline过滤、加工、存储的Item也会相应的改变,简而言之就是浅拷贝的问题,解决方法深拷贝。

  所以最终建议使用copy.deepcopy函数进行深拷贝

def parse(self, response):
        province_list = response.xpath("//div[@class='city_province']")
        for province in province_list:
            province_name = province.xpath("./div/text()").get()
            city_list = province.xpath("./ul/li/a")
            for city in city_list:
                item = {}
                city_name = city.xpath("./text()").get()
                city_url = city.xpath("./@href").get()
                # 链接分为两类:没有二手房的链接和有二手房的链接
                if "fang" in city_url:
                    continue
                # print(province_name, city_name, city_url)
                # 将所有城市的链接转化为二手房的链接
                city_esf_url = city_url + "ershoufang/co32/"
                item["province"] = province_name
                item["city"] = city_name
                yield scrapy.Request(url=city_esf_url, callback=self.parse_city, meta={"item": copy.deepcopy(item)})

  另外建议,进行深拷贝的位置也是有讲究的,必须在meta里进行深拷贝,否则也会出现重复。

原文地址:https://www.cnblogs.com/loveprogramme/p/13138450.html