[求助] Scrapy 报错 KeyError: 'item'

2019-08-19 23:39:41 +08:00
 viiii

如题,在写爬虫时,碰到这个错误 使用的是 crawlspider 通用爬虫,下面是代码(先调用 parse_a,再调用 parse_b)

    name = 'crawl_spider'
    allowed_domains = ['baidu.com']
    start_urls = ['https://www.baidu.com']

    rules = (...)
    
def parse_a(self,response)
	...
    yield item  # item 定义省略
    yield scrapy.Request(url=url,callback=self.parse_b,meta={'item':item})
    
def parse_b(self,response)
	item = response.meta["item"]  # 获取 parse_a 传递过来的 item 对象
    print(item)
    ...

运行代码后报错如下:

Traceback (most recent call last):
  File "C:\Users\mypc\Anaconda3\lib\site-packages\scrapy\utils\defer.py", line 102, in iter_errback
    yield next(it)
  File "C:\Users\mypc\Anaconda3\lib\site-packages\scrapy\spidermiddlewares\offsite.py", line 29, in process_spider_output
    for x in result:
  File "C:\Users\mypc\Anaconda3\lib\site-packages\scrapy\spidermiddlewares\referer.py", line 339, in <genexpr>
    return (_set_referer(r) for r in result or ())
  File "C:\Users\mypc\Anaconda3\lib\site-packages\scrapy\spidermiddlewares\urllength.py", line 37, in <genexpr>
    return (r for r in result or () if _filter(r))
  File "C:\Users\mypc\Anaconda3\lib\site-packages\scrapy\spidermiddlewares\depth.py", line 58, in <genexpr>
    return (r for r in result or () if _filter(r))
  File "C:\Users\mypc\Anaconda3\lib\site-packages\scrapy\spiders\crawl.py", line 78, in _parse_response
    for requests_or_item in iterate_spider_output(cb_res):
  File "d:\Python_project\2019-08-18\novel\novel\spiders\crawl_spider", line 63, in parse_chapter_detail
    item = response.meta["item"]  # 获取前面传递过来的 item 对象
KeyError: 'item'

猜测可能是传递 item 哪里没搞对导致的错误

PS:使用 crawlspider 这样传递 item 是否正确?如果不对,应该怎么在不同方法间传递 item 对象?

1602 次点击
所在节点    问与答
7 条回复
warcraft1236
2019-08-20 10:02:49 +08:00
debug 看一下,怀疑 response 的 meta 里边没有 item
viiii
2019-08-20 12:20:56 +08:00
@warcraft1236 打印一下发现确实没有 item,已经在上面追加附言
请问这里该怎么传递 item? 爬取的目标信息分布在不同级别的页面中,无法一次全部获取完整
warcraft1236
2019-08-20 13:15:29 +08:00
首先,你这个 item 对应的 value,是要传递什么数据,如果是需要持久化的,应该用 pipeline
warcraft1236
2019-08-20 13:18:02 +08:00
我记得 scrapy 官方的教程里边,meta 就是这么传递,你应该没写错,还是得 debug 一下,看看执行的时候发生了什么
viiii
2019-08-20 15:04:37 +08:00
@warcraft1236
以采集某小说内容为例,
首先在 parse_a 中获取 标题 /简介 /作者等信息, yield 给 pipeline 存到数据表 a 中; 再将 item 传递给 parse_b
第二步, 获取章节正文,存到数据表 b 中 (由于章节正文页面不显示书籍标题,只有章节标题,所以存到表 b 中的时候,需要从 parse_a 里传递书籍标题到 parse_b 中)

基本流程就是这个样子,用 crawlspider 第一次遇到这个情况
viiii
2019-08-20 16:13:26 +08:00
还有一点比较奇怪, 同样传递方式,在 spider (普通爬虫)里面就一切正常, 换到 crawlspider(通用爬虫)就报 KeyError 错误
warcraft1236
2019-08-21 09:25:09 +08:00
@viiii 才注意到,我一般都是继承 spider,没继承过 crawlspider,不过感觉 meta 这块应该没有什么改变才是,你可以看看 crawlspider 的实现

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/593335

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX