首页 > 解决方案 > Scrapy 使用项目和项目加载器处理多个蜘蛛数据处理

问题描述

我有一个有太多蜘蛛的大项目,我在我的机器人中进行数据处理而不是使用itemsanditem-loaders我想重构整个项目机器人并在项目中分配数据处理但问题是我想定期更新我的机器人和每个网站我爬的不一样,所以数据处理也不一样,如果我想在items中实现我的数据处理,功能肯定很多,以后会花很多钱所以我在找在其他地方进行数据处理的最佳实践方法。此外,数据库在机器人文件中,删除它们也是完美的。任何建议都意义重大。

样品, 机器人

import scrapy
from tutorial.items import SampleScraper
from scrapy.loader import ItemLoader


class sample(scrapy.Spider):
    name = "sample"
    start_urls = [
        ""
    ]


    def parse(self, response):

        item_loader = ItemLoader(item = SampleScraper(), selector=response)

        item_loader.add_xpath('title', "//meta[@property='og:title']/@content")
        item_loader.add_xpath('price', "//div[@class='product-info-buy p-15']/div[@class='product-price-wrap']/h5[@class='product-price']/span[@ng-bind='getPrice()|number']/text()")


        yield item_loader.load_item()

样品,物品

# Define here the models for your scraped items
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy
from scrapy.loader import ItemLoader
from itemloaders.processors import TakeFirst, MapCompose
from w3lib.html import remove_tags



def remove_t(value):
    return value.replace('\t', '')


def replacing(value):
    return value.replace(',', '')


class SampleScraper(scrapy.Item):
    # define the fields for your item here like:

    title = scrapy.Field(input_processor = MapCompose(remove_tags, remove_t), output_processor = TakeFirst())
    price = scrapy.Field(input_processor = MapCompose(remove_tags, replacing), output_processor = TakeFirst())

标签: pythonscrapy

解决方案


对于具有许多蜘蛛的项目,更好的做法是创建一个基本项目类和基本项目加载器BaseItemLoader,其中包含所有项目中使用的公共字段和处理器,并且对于每个项目,您将创建扩展的自定义项目加载器BaseItemLoader,因此您可以为每个项目配备您的自定义现场处理器。

假设title字段及其输入处理器对所有项目都是通用的,而所有其他输入/输出处理器和字段将特定于每个项目 - 例如您示例中的示例蜘蛛。

import scrapy
from scrapy.loader import ItemLoader
from itemloaders.processors import TakeFirst, MapCompose
from w3lib.html import remove_tags


def remove_t(value):
    return value.replace('\t', '')


def replacing(value):
    return value.replace(',', '')


class BaseItem(scrapy.Item):
    title = scrapy.Field()
    

class BaseItemLoader(ItemLoader):
    default_item_class = BaseItem
    title_in = MapCompose(remove_tags, remove_t)

----

class SampleScraper(BaseItem):
    price = scrapy.Field()


class SampleItemLoader(ItemLoader):
    default_item_class = SampleScraper
    title_out = TakeFirst()
    price_in = MapCompose(remove_tags, replacing)
    price_out = TakeFirst()

然后在您的示例蜘蛛代码中,您只需调用项目加载器:

...
def parse(self, response):

    item_loader = SampleItemLoader(selector=response)
    item_loader.add_xpath('title', "//meta[@property='og:title']/@content")
    item_loader.add_xpath('price', "//div[@class='product-info-buy p-15']/div[@class='product-price-wrap']/h5[@class='product-price']/span[@ng-bind='getPrice()|number']/text()")

    yield item_loader.load_item()

推荐阅读