ItemLoader空值报错问题
1. 问题描述
1) 目标网站:https://news.cnblogs.com/
2) 问题背景:
在抓取文章的tags时,有些文章有这个信息,有些文章没有这个信息。scrapy-spider在解析的时候使用itemloader机制解析填充数据。但是当遇到页面没有这个属性的文章时,解析为空,itemloader默认不填充,数据对象为None。在向数据库保存数据时就会报错keyerror。
2. 解决思路
1) 参考网上文章
大概思路就是:要么不用itemloader,要么就重载Mapcompose对象。
2) 灵光一现解决方案:
修改之前的源码:
修改之后的源码
item_loader.add_xpath('tags', xpath=".//a[@class='catalink']/text()")
item_loader.add_value('tags', 'null')
解释:
可以将add_xpath()函数和add_value()函数配合使用。
经过测试,将add_xpath()函数写在add_value()之前,那么如果前者没有匹配到数据时,就会将add_value()函数中的value值到字段中,测试结果是xpath匹配到的item按照xpath匹配结果填充字段,没有匹配到xpath的item按照add_value填充了字段。
反过来,如果将add_value()函数写在add_xpath()之前,则优先匹配add_value()函数,测试结果也是全都变成了add_value()函数中的“null”字符串了。
也就是说这样修改后,代码逻辑就变成了,‘add_xpath()'匹配到了就填充匹配结果,没有匹配到,就填充’add_value’中的默认值。
3) 重载ItemLoader类中的add_xpath()函数
源码中的add_xpath():
def add_xpath(self, field_name, xpath, *processors, **kw):
values = self._get_xpathvalues(xpath, **kw)
self.add_value(field_name, values, *processors, **kw)
根据源码可以看出,add_xpath()函数通过xpath匹配之后也是要调用add_value()函数填充数据,所以可以在调用add_value()函数填充之前,添加判断逻辑,先判断values是否为空,如果values为空就给一个默认值让add_value()填充,如果values不为空,就按照values填充。
def add_xpath(self, field_name, xpath, *processors, **kw):
values = self._get_xpathvalues(xpath, **kw)
if values:
self.add_value(field_name, values, *processors, **kw)
else:
self.add_value(field_name, 'null', *processors, **kw)