【问题标题】:How to get order of fields in Scrapy item如何获取 Scrapy 项目中的字段顺序
【发布时间】:2016-12-23 01:12:03
【问题描述】:

我有兴趣保持对 scrapy 项目中字段名称顺序的引用。这个存储在哪里?

>>> dir(item)
Out[7]: 
['_MutableMapping__marker',
 '__abstractmethods__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__delitem__',
 '__dict__',
 '__doc__',
 '__eq__',
 '__format__',
 '__getattr__',
 '__getattribute__',
 '__getitem__',
 '__hash__',
 '__init__',
 '__iter__',
 '__len__',
 '__metaclass__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__setitem__',
 '__sizeof__',
 '__slots__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 '_abc_cache',
 '_abc_negative_cache',
 '_abc_negative_cache_version',
 '_abc_registry',
 '_class',
 '_values',
 'clear',
 'copy',
 'fields',
 'get',
 'items',
 'iteritems',
 'iterkeys',
 'itervalues',
 'keys',
 'pop',
 'popitem',
 'setdefault',
 'update',
 'values']

我尝试了 item.keys(),但它返回了一个无序的字典

【问题讨论】:

  • 我认为Scrapy 不会保持项目中字段的顺序(但我不确定)。
  • 实际上(截至今天),如果您在process_item(self, item, spider) 内部(在您的pipelines.py 中),那么使用item.keys() 保留在items.py 文件中找到的顺序。但是,如果您尝试通过从items.py 导入类来获取项目keys,则使用self.ikeys = YourItem.fields.keys() 时找到的顺序将按字母 顺序排列。下面的答案没有解决这个问题。

标签: python scrapy


【解决方案1】:

Item 类有一个 dict 接口,将值存储在 _values dict 中,它不跟踪键顺序 (https://github.com/scrapy/scrapy/blob/1.5/scrapy/item.py#L53)。我相信您可以从Item 继承并覆盖__init__ 方法以使该容器成为Ordereddict

from scrapy import Item
from collections import OrderedDict

class OrderedItem(Item):
    def __init__(self, *args, **kwargs):
        self._values = OrderedDict()
        if args or kwargs:  # avoid creating dict for most common case
            for k, v in six.iteritems(dict(*args, **kwargs)):
                self[k] = v

然后该项目保留分配值的顺序:

In [28]: class SomeItem(OrderedItem):
    ...:     a = Field()
    ...:     b = Field()
    ...:     c = Field()
    ...:     d = Field()
    ...: 
    ...: i = SomeItem()
    ...: i['b'] = 'bbb'
    ...: i['a'] = 'aaa'
    ...: i['d'] = 'ddd'
    ...: i['c'] = 'ccc'
    ...: i.items()
    ...: 
Out[28]: [('b', 'bbb'), ('a', 'aaa'), ('d', 'ddd'), ('c', 'ccc')]

【讨论】:

  • 谢谢,这是一个很好的答案。这是您对stackoverflow.com/questions/41273314/… 的回答的后续行动。我想构建一个“即插即用”管道对象,我可以将其放入未来的scrapy项目中(stackoverflow.com/questionI意识到数据集包将支持插入有序字典s/41106509/sqlalchemy-dynamically-create-table-from-刮擦项目)。使用数据集包,您可以插入字典,但会丢失项目字段的顺序。
  • 我想找到一种在插入记录时跟踪该顺序的方法。我意识到数据集包将支持插入有序 dicts ,但我需要一种方法来根据项目字段顺序以正确的顺序传递键。
  • 我猜你可以传递OrderedItem 实例的_values 属性,因为它是OrderedDict。但是我不确定您的预期结果是什么,我不知道有任何数据库会“保留字段的顺序”。如果您使用的是 SQL(我想您是,您在上一个问题中提到了 SQLite),您始终可以在 SELECT 语句中指定字段顺序。
  • 没错,我将信息导出到 csv 文件,所以它真的不重要。但是在开发过程中,我喜欢在我的 gui 中控制 sqllite 表中字段的顺序,以便于比较特定字段。
  • 对,然后编写一个自定义查询来指定字段的顺序,而不仅仅是select * from ... 是恕我直言的方法:-)
猜你喜欢
  • 2023-03-05
  • 1970-01-01
  • 2014-10-03
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-13
相关资源
最近更新 更多