如题,在写爬虫时,碰到这个错误 使用的是 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 对象?
parse_b 中打印了一下meta的信息, 如下所示:
>>>print("meta info ----->")
>>>print(response.meta)
meta info ----->
{'rule': 2, 'link_text': '第一千九百三十三章 转身', 'depth': 2, 'download_timeout': 180.0, 'download_slot': 'www.23us.so', 'download_latency': 0.23895788192749023}
可能是前面parse方法传入的item没有存进去, 现在该怎么传递item? 更迷糊了...
1
warcraft1236 2019-08-20 10:02:49 +08:00
debug 看一下,怀疑 response 的 meta 里边没有 item
|
2
viiii OP @warcraft1236 打印一下发现确实没有 item,已经在上面追加附言
请问这里该怎么传递 item? 爬取的目标信息分布在不同级别的页面中,无法一次全部获取完整 |
3
warcraft1236 2019-08-20 13:15:29 +08:00
首先,你这个 item 对应的 value,是要传递什么数据,如果是需要持久化的,应该用 pipeline
|
4
warcraft1236 2019-08-20 13:18:02 +08:00
我记得 scrapy 官方的教程里边,meta 就是这么传递,你应该没写错,还是得 debug 一下,看看执行的时候发生了什么
|
5
viiii OP @warcraft1236
以采集某小说内容为例, 首先在 parse_a 中获取 标题 /简介 /作者等信息, yield 给 pipeline 存到数据表 a 中; 再将 item 传递给 parse_b 第二步, 获取章节正文,存到数据表 b 中 (由于章节正文页面不显示书籍标题,只有章节标题,所以存到表 b 中的时候,需要从 parse_a 里传递书籍标题到 parse_b 中) 基本流程就是这个样子,用 crawlspider 第一次遇到这个情况 |
6
viiii OP 还有一点比较奇怪, 同样传递方式,在 spider (普通爬虫)里面就一切正常, 换到 crawlspider(通用爬虫)就报 KeyError 错误
|
7
warcraft1236 2019-08-21 09:25:09 +08:00
@viiii 才注意到,我一般都是继承 spider,没继承过 crawlspider,不过感觉 meta 这块应该没有什么改变才是,你可以看看 crawlspider 的实现
|