Я использую фреймворк 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 не из спайдера (например, из пайплайнов)? Или как иначе увеличить связность и уменьшить зацепление?