为什么Scrapy的Field是字典?
基本上,我有一个很普通的设置,一个从 CrawlSpider
继承来的爬虫,还有一个包含三个字段的项目,长得像这样:
class AppdexItem(Item):
name = Field()
url = Field()
desc = Field()
当我的爬虫解析一个响应时,它会填充一个项目,像这样:
i = AppdexItem()
name = hxs.select("//h1[@class='doc-banner-title']/text()")
i['name'] = name.extract()[0]
现在我有点困惑,因为我读到的关于 Field 的内容。它实际上就是 它的实现:
class Field(dict):
"""Container of field metadata"""
它其实就是一个简单的 dict
(字典)。我在想为什么会这样,还盯着这个实现看了一会儿,但还是搞不懂。所以我在一个应该被解析成项目的页面上运行了 scrapy shell
,结果得到了这个:
In [16]: item = spider.parse_app(response)
In [17]: item.fields
Out[17]: {'desc': {}, 'name': {}, 'url': {}}
In [18]: item['name']
Out[18]: u'Die Kleine Meerjungfrau'
什么情况?要么我做错了什么(我按照官方教程和示例的指示做的),要么 Field
作为一个 dict
根本没什么意义。
有人能给我解释一下吗?
2 个回答
3
字段 is 被用作字典来存储元数据;一个用例是为 ItemLoader 指定输入和输出处理器。你可以查看这个链接了解更多信息:http://doc.scrapy.org/en/master/topics/loaders.html#declaring-input-and-output-processors。
我个人认为,Scrapy 如果能支持普通的字典而不需要任何元数据会更好,但这又是另一个话题。
8
历史原因。以前在字段上会附加一些元数据,这些数据是存储在字典里的。我猜是因为字典有一个方便的(键=值)构造方式,所以才用它。你可以看到最后一次使用这个字典的地方是在这个提交中被移除了。到现在为止,这样的区别已经不大了,它其实可以只是一个普通的对象(不过如果还有代码依赖于它是字典的话,改起来可能会有点麻烦)。