我正在从中导入Scrapy项目密钥items.py到pipelines.py。问题在于,导入项目的顺序与items.py文件中定义的顺序不同。
Scrapy
items.py
pipelines.py
我的items.py档案:
class NewAdsItem(Item): AdId = Field() DateR = Field() AdURL = Field()
在我的pipelines.py:
from adbot.items import NewAdsItem ... def open_spider(self, spider): self.ikeys = NewAdsItem.fields.keys() print("Keys in pipelines: \t%s" % ",".join(self.ikeys) ) #self.createDbTable(ikeys)
输出为:
Keys in pipelines: AdId,AdURL,DateR
而不是预期的:AdId,DateR,AdURL。
AdId,DateR,AdURL
如何确保导入的订单保持不变?
注意:这可能与如何获取Scrapy项目中的字段顺序有关,但是由于Python3文档指出列表和字典应保留其顺序,因此这还不是很清楚。另请注意,在使用process_item()和使用时item.keys(),将保留顺序!但我需要访问键,以便前 项的刮。
process_item()
item.keys()
我可以使它起作用的唯一方法是以下列方式使用此解决方案。
from scrapy.item import Item, Field from collections import OrderedDict from types import FunctionType class StaticOrderHelper(type): # Requires Python3 def __prepare__(name, bases, **kwargs): return OrderedDict() def __new__(mcls, name, bases, namespace, **kwargs): namespace['_field_order'] = [ k for k, v in namespace.items() if not k.startswith('__') and not k.endswith('__') and not isinstance(v, (FunctionType, classmethod, staticmethod)) ] return type.__new__(mcls, name, bases, namespace, **kwargs) class NewAdsItem(metaclass=StaticOrderHelper): AdId = Field() DateR = Field() AdURL = Field()
然后使用以下命令将该_field_order项目导入你piplines.py的:
_field_order
piplines.py
... from adbot.items import NewAdsItem ... class DbPipeline(object): ikeys = NewAdsItem._field_order ... def createDbTable(self): print("Creating new table: %s" % self.dbtable ) print("Keys in creatDbTable: \t%s" % ",".join(self.ikeys) ) ...
现在,我可以按照正确的外观顺序创建新的数据库表,而不必担心Python以一种意想不到的方式对字典进行奇怪的排序。