Scrapy如何使用Loader忽略字段为空的项

6 投票
1 回答
2794 浏览
提问于 2025-04-18 07:19

我想知道怎么处理那些没有填满所有字段的项目,也就是想把它们丢掉,因为在scrapyd的输出中,我得到了那些没有填满所有字段的页面。

我有以下代码:

class Product(scrapy.Item):
    source_url = scrapy.Field(
        output_processor = TakeFirst()
    )
    name = scrapy.Field(
        input_processor = MapCompose(remove_entities),
        output_processor = TakeFirst()
    )
    initial_price = scrapy.Field(
        input_processor = MapCompose(remove_entities, clear_price),
        output_processor = TakeFirst()
    )
    main_image_url = scrapy.Field(
        output_processor = TakeFirst()
    )

解析器:

def parse_page(self, response):
    try:
        l = ItemLoader(item=Product(), response=response)
        l.add_value('source_url', response.url)
        l.add_css('name', 'h1.title-product::text')
        l.add_css('main_image_url', 'div.pics a img.zoom::attr(src)')

        l.add_css('initial_price', 'ul.precos li.preco_normal::text')
        l.add_css('initial_price', 'ul.promocao li.preco_promocao::text')

        return l.load_item()

    except Exception as e:
        print self.log("#1 ERRO: %s" % e), response.url

我想用Loader来处理这些,而不是自己创建选择器(这样可以避免处理项目两次)。我想我可以在管道中丢掉它们,但这可能不是最好的方法,因为这些项目并不有效。

1 个回答

10

数据验证是管道的一个典型应用场景。在你的情况下,你只需要写一些简单的代码来检查必填字段,像下面这样:

from scrapy.exceptions import DropItem

class YourPersonalPipeline(object):
    def process_item(self, item, spider):
        required_fields = [] # your list of required fields
        if all(field in item for field in required_fields):
            return item
        else:
            raise DropItem("your reason")

你需要在settings.py中启用管道,可以在scrapy文档中了解更多信息

撰写回答