作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想抓取一页数据(使用 Python Scrapy 库),而不必在页面上定义每个单独的字段。相反,我想使用元素的 id
作为字段名称动态生成字段。
起初我认为最好的方法是建立一个收集所有数据的管道,并在收集到所有数据后将其输出。
然后我意识到我需要将数据传递到项目中的管道,但我无法定义项目,因为我不知道它需要哪些字段!
解决这个问题的最佳方法是什么?
最佳答案
旧方法不适用于 item loaders并不必要地使事情复杂化。这是实现灵活项目的更好方法:
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!"
结果:
{'foo': ['bar', 555], 'baz': [123, 'test'], 'abc': ['xyz']}it's not a cat!
Okay, I've found a solution. It's a bit of "hack" but it works..
A Scrapy Item stores the field names in a dict called fields
. When adding data to an Item it checks if the field exists, and if it doesn't it throws and error:
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
好了。
现在,当您向项目添加数据时,如果该项目未定义该字段,则会添加该字段,然后数据将正常添加。
关于python - 无需明确定义要抓取的每个字段即可抓取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5069416/
这实际上是我问的问题的一部分here ,该问题没有得到答复,最终被标记为重复。 问题:我只需使用 @Autowired 注释即可使用 JavaMailSender。我没有通过任何配置类公开它。 @Co
我是一名优秀的程序员,十分优秀!