1

我正在尝试使用 itemLoader 为 Scrapy 中的空项目提供默认值,就像在 items.py 中一样:

prod_specs = Field(
    default=[],
    input_processor=MapCompose(unicode_to_str, strip_tabs_new_lines),
)

所以如果 prod_specs 没有设置,它应该给它一个空对象。但它不起作用。如果我尝试将字段存储到数据库中item['prod_specs'].

我收到一条错误消息,告诉我密钥不存在:

exceptions.KeyError: 'prod_specs' 

如果未设置其他字段,则相同。我认为我正在使用item['prod_specs']而不是 items.py 中的 itemLoader 的事实导致了错误。但我不确定。

那你们怎么看?您对此有解决方案吗?

4

1 回答 1

1

编辑:官方文档似乎已过时,字段默认值不再起作用(请参阅https://github.com/scrapy/scrapy/issues/560)。所以另一种选择是使用管道为项目分配默认值:

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 用作项目。以下是如何设置您的项目和项目加载器。

项目.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)
    )

蜘蛛/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 并定义默认处理器。

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

于 2014-07-12T16:54:56.173 回答