Update:
旧方法不适用于物品装载机 http://doc.scrapy.org/en/latest/topics/loaders.html并使事情变得不必要地复杂化。这是实现灵活项目的更好方法:
from scrapy.item import BaseItem
from scrapy.contrib.loader import ItemLoader
class FlexibleItem(dict, BaseItem):
pass
if __name__ == '__main__':
item = FlexibleItem()
loader = ItemLoader(item)
loader.add_value('foo', 'bar')
loader.add_value('baz', 123)
loader.add_value('baz', 'test')
loader.add_value(None, {'abc': 'xyz', 'foo': 555})
print loader.load_item()
if 'meow' not in item:
print "it's not a cat!"
Result:
{'foo': ['bar', 555], 'baz': [123, 'test'], 'abc': ['xyz']}
it's not a cat!
旧的解决方案:
好的,我已经找到解决方案了。这有点“黑客”,但它有效。
Scrapy Item 将字段名称存储在名为的字典中fields
。当向项目添加数据时,它会检查该字段是否存在,如果不存在,则会抛出错误:
def __setitem__(self, key, value):
if key in self.fields:
self._values[key] = value
else:
raise KeyError("%s does not support field: %s" %\
(self.__class__.__name__, key))
你能做的就是覆盖这个__setitem__
函数不那么严格:
class FlexItem(Item):
def __setitem__(self, key, value):
if key not in self.fields:
self.fields[key] = Field()
self._values[key] = value
就这样吧。
现在,当您向项目添加数据时,如果该项目没有定义该字段,则会添加该字段,然后正常添加数据。