YardalGedal
@YardalGedal
yeah boy

Корректно ли в таком случае использовать класс Meta?

Я использую фреймворк Scrapy и у меня есть два сайта которые парсятся по примерно одинаковому алгоритму и хочется несколько абстрагировать и объединить их функционал. Проблема в том, что каждому спайдеру соответствует своя моделька базы данных, своя схема данных для внешнего сервиса, свой Scrapy ItemLoader и так далее. Моя идея заключается в следующем, реализовать некий абстрактный класс не содержащий вообще ничего
class AbstractSpider(scrapy.Spider):
    name = ''
    allowed_domains = ()
    start_urls = ()

    class Meta:
        model = None
        schema = None
        history_model = None

        _loader = None

    def parse(self, response: scrapy.http.HtmlResponse) -> Any:
        raise NotImplementedError

    def _gen_item(self, response: scrapy.http.HtmlResponse) -> scrapy.Item:
        raise NotImplementedError

    def _add_fields(self, loader: Meta._loader) -> None:
        raise NotImplementedError


Далее реализовать общий класс для обоих спайдеров:
class AutoSpider(AbstractSpider, scrapy.Spider):
    class Meta:
        model = models.AutoModel
        schema = schemas.AUTO_SCHEMA
        history_model = models.HistoryAutoModel

        _loader = AutoItemLoader
        full_loader = FullAutoItemLoader
        short_loader = ShortAutoItemLoader

    def parse(self, response: scrapy.http.HtmlResponse) -> Any:
        raise NotImplementedError

    def _gen_item(self, response: scrapy.http.HtmlResponse) -> scrapy.Item:
        ...
        def _add_fields(self, loader: Meta._loader) -> None:
        if isinstance(loader, self.Meta.full_loader):
            self._add_from_full(loader)
        elif isinstance(loader, self.Meta.short_loader):
            self._add_from_short(loader)

    def _add_from_full(self, loader: Meta.full_loader) -> None:
        raise NotImplementedError

    def _add_from_short(self, loader: Meta.short_loader) -> None:
        raise NotImplementedError
...

И дальше наследовать уже каждый спайдер реализуя в них класс Meta с изменяющими поведение общего для них класса.

На сколько корректно так делать? На сколько корректно будет обращаться к Meta не из спайдера (например, из пайплайнов)? Или как иначе увеличить связность и уменьшить зацепление?
  • Вопрос задан
  • 110 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы