我试图使用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']
而不是itemLoader,如items.py,正在导致错误。但我不确定。
你们怎么看?你有解决办法吗?
edit:官方文档似乎过时了,Field默认值不再工作(参见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作为Item。下面是如何设置你的项目和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)
)
蜘蛛/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,通过这种方式,您可以使用单个管道向任意数量的数据库写入任意数量的对象。