为什么Scrapy的Field是字典?

4 投票
2 回答
2549 浏览
提问于 2025-04-17 16:01

基本上,我有一个很普通的设置,一个从 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

历史原因。以前在字段上会附加一些元数据,这些数据是存储在字典里的。我猜是因为字典有一个方便的(键=值)构造方式,所以才用它。你可以看到最后一次使用这个字典的地方是在这个提交中被移除了。到现在为止,这样的区别已经不大了,它其实可以只是一个普通的对象(不过如果还有代码依赖于它是字典的话,改起来可能会有点麻烦)。

撰写回答