Scrapy动态定义Item类字段报AttributeError的解决方法
问题原因
报错核心有两点:
- 你重写
PostscrapeItem的__init__方法时,没有调用父类scrapy.Item的初始化方法,父类初始化逻辑会给实例绑定内部存储用的_values属性,缺失这个属性就会抛出你看到的AttributeError: _values错误。 - 你对Scrapy Item的字段存储逻辑理解有误:
scrapy.Field()是类级别声明的属性,不是绑定到实例__dict__的实例属性,你在实例初始化阶段往self.__dict__塞Field的写法完全不符合Item的设计,就算绕过报错也无法正常使用字段。
额外还有个语法错误:Scrapy Item获取字段名的方法是小写开头的keys(),不存在大写开头的Keys()方法,调用会抛属性错误。
修复方案
不要在__init__实例方法里定义字段,直接在类定义完成后,通过类动态绑定的方式批量添加Field即可,完全不需要重写__init__。
注意读取CSV时的细节:如果你的fields.csv没有表头,第一行直接就是字段名,调用pd.read_csv时要加header=None参数,否则第一行字段会被pandas识别为列名,导致第一个字段丢失。
修复后可直接运行的代码:
import pandas as pd import scrapy # 读取字段配置,无表头的话记得加header=None参数:pd.read_csv(xxx, header=None) fields = pd.read_csv('E:/pythonProject/webscrapping/postscrape/fields.csv') # 无表头的话这里取列不要加引号:list(fields[0]) fields = list(fields['0']) fields.insert(0, 'Company') class PostscrapeItem(scrapy.Item): pass # 类层面动态绑定字段,符合Scrapy Item的字段识别逻辑 for field_name in fields: setattr(PostscrapeItem, field_name, scrapy.Field()) # 功能测试 item = PostscrapeItem() print(item.keys())
运行后会正常打印所有你从CSV读取到的、加上Company的所有字段名,不会再报属性错误。
内容的提问来源于stack exchange,提问作者Zain Asif
相关产品推荐
相关产品推荐

