Python 刮痧:什么';使用itemloader i.c.w.a Postgres管道的最佳方式是什么?

Python 刮痧:什么';使用itemloader i.c.w.a Postgres管道的最佳方式是什么?,python,postgresql,scrapy,scrapy-spider,Python,Postgresql,Scrapy,Scrapy Spider,我正在尝试使用itemLoader为Scrapy中的空项目提供一个默认值,如items.py中所示: prod_specs = Field( default=[], input_processor=MapCompose(unicode_to_str, strip_tabs_new_lines), ) 因此,如果未设置prod_specs,则应为其提供一个空对象。但它不起作用。如果我尝试使用item['prod\u specs']将字段存储到数据库中。 我收到一个错误,告诉我密钥

我正在尝试使用itemLoader为Scrapy中的空项目提供一个默认值,如items.py中所示:

prod_specs = Field(
    default=[],
    input_processor=MapCompose(unicode_to_str, strip_tabs_new_lines),
)
因此,如果未设置prod_specs,则应为其提供一个空对象。但它不起作用。如果我尝试使用
item['prod\u specs']将字段存储到数据库中。

我收到一个错误,告诉我密钥不存在:

exceptions.KeyError: 'prod_specs' 
如果未设置其他字段,则对其执行相同操作。我认为我使用的是
item['prod\u specs']
,而不是items.py中的itemLoader,这是导致错误的原因。但我不确定


你们怎么想?您有解决方案吗?

编辑:官方文档似乎过时了,字段默认值不再起作用(请参阅)。 因此,另一个选项是使用管道为项目指定默认值:

def parse_item(self, item, spider):
    if "prod_specs" not in item: item['prod_specs'] = []
    return item
或在psycopg2插入期间:

def parse_item(self, item, spider):
    cur.execute("insert into mytable(prod_specs) values(%s)",
                item.get('prod_specs',[]))
    return

您正在尝试将ItemLoader用作项目。 下面是如何设置项目和项目加载器

items.py

from scrapy.item import Field, Item
from scrapy.contrib.loader.processor import MapCompose

class Product(Item):
    prod_specs = Field(
        default=[],
        input_processor=MapCompose(unicode_to_str, strip_tabs_new_lines)
    )
spider/myspider.py

from scrapy.contrib.loader import ItemLoader
from myproject.items import Product

def parse(self, response):
    l = MyLoader(item=Product(), response=response)
    l.add_xpath('prod_specs', '//div[@class="prod_specs"]')
    return l.load_item()
如果您打算使用许多不同的项,那么应该将ItemLoader子类化并定义默认处理器


这足以回答你的问题吗?你提到你想写一篇博士后文章。我发现最简单的方法是使用SQLAlchemy,通过这种方法,您可以使用单个管道将任意多个对象写入任意多个数据库。

我已经完成了这一部分,但现在的问题是将这些信息保存在PostgreSQL中。我使用的是psycopg2,目前为止运行良好。但是我使用item来保存数据:
def process\u item(self,item,spider):
然后
item['prod\u specs']
如果该项为空,它不会保存空数组,而是返回一个错误。这就是为什么我认为我也需要在管道中使用ItemLoader的原因,对吗?好的,那么,在管道中,如果“产品规格”不在项目中,您可以添加
:项目['prod\u spec']=[]
在插入之前,或者
cur.execute('insert into my\u table(prod\u specs)值(%s)',(项目['prod\u specs']如果项目中的'prod\u specs'在其他[]))
在插入过程中。但是如果我必须进行检查或者项目不是空的,Itemloader默认方法的目的是什么???我的错,看起来我们被官方文档误导了:。因此,在本例中,我将使用管道加载默认值。