Scrapy使用meta传递JSON值未更新问题求助
解决Scrapy中meta传递JSON数据始终不变的问题
看起来你遇到的是Scrapy请求间传递可变对象时的引用共享问题,再加上循环逻辑的小失误,才导致data_rest始终是同一个值。咱们一步步来解决:
1. 先修复循环逻辑的错误
看你代码里的这段循环:
for key, value in value_json.items(): #loop the json for values in value: # values will show me as dictionay of dictionary # thats like {"blabla":{"key1":"value1","key1":"value2"}} if values == "blabla": get_url = "http://www.example.com/" yield Request( url=get_url+values["id_url"], meta={"data_rest":values}, callback=self.second_function )
这里有个关键问题:当value是字典(比如{"blabla": {...}})时,for values in value:会遍历字典的键,也就是values是字符串"blabla",而非你想要的子字典。这时候values["id_url"]其实会报错,而且你把字符串传到meta里,后续自然得不到正确的更新。
你应该改成遍历字典的键值对,拿到对应的子字典:
for key, value in value_json.items(): # 遍历value字典的键和对应的子字典 for sub_key, sub_value in value.items(): if sub_key == "blabla": get_url = "http://www.example.com/" yield Request( url=f"{get_url}{sub_value['id_url']}", meta={"data_rest": sub_value}, # 这里传递正确的子字典 callback=self.second_function )
2. 解决可变对象的引用传递问题
如果你的sub_value是同一个字典对象在循环中被修改(虽然你的场景里看起来不是,但保险起见),Scrapy传递可变对象时会因为引用共享,导致所有请求的data_rest最后都变成循环最后一次的值。这时候可以用copy.deepcopy()复制字典,确保每个请求的meta里都是独立的对象:
首先导入copy模块:
import copy
然后在yield Request时修改meta:
meta={"data_rest": copy.deepcopy(sub_value)},
3. 可选:传递数据到后续函数
如果你的next_function也需要用到data_rest,别忘了在second_function的Request里把它也放进meta,不然后续函数就拿不到了:
yield scrapy.Request( url=loop_url_menu, headers=self.session, meta = { 'dont_redirect': True, 'handle_httpstatus_list': [302], 'data_rest': response.meta['data_rest'] # 传递数据到下一个函数 }, callback=self.next_function )
调整完这些之后,你应该就能在second_function里拿到每次循环对应的不同data_rest数据了。
内容的提问来源于stack exchange,提问作者Stefani Johnsson
相关产品推荐
相关产品推荐

