Расширяемая Python-система для двух независимых задач:
- полного регионального сбора товарных каталогов без входной таблицы;
- строгого сопоставления товаров магазина с входной номенклатурой.
Встроены адаптеры Лемана Про, Максидом и Сатурн. Новые магазины подключаются как Python-плагины без изменения crawler, proxy, output и checkpoint-слоёв.
- произвольный регион: код, название, страна, timezone, locale, store-specific slug;
- отдельный base URL и cookies для каждого сайта;
- полный discovery через
robots.txt, sitemap/sitemap-index и обход каталога; - сбор JSON-LD, offer, SKU/MPN/GTIN, бренда, цены, валюты, наличия, описания, категории, breadcrumbs, изображений и всех найденных характеристик;
- опциональное сохранение исходного HTML для lossless-повторного разбора;
- обязательный provenance: магазин, домен, URL, регион и UTC-время получения;
- карта
field_sources, указывающая страницу-источник каждого заполненного поля; - JSONL/NDJSON или CSV, checkpoint после каждой карточки и
--resume; - строгий matcher по SKU, бренду, серии, размеру, весу, объёму, цвету и исполнению;
- HTTP → Playwright fallback для защищённых страниц;
- бесплатные, платные и собственные HTTP(S)/SOCKS5 proxy-пулы;
- registry
StoreAdapterи внешние модули изSTORE_PLUGINS.
Windows PowerShell:
Set-ExecutionPolicy -Scope Process Bypass
.\setup.ps1
Copy-Item .env.example .envИли вручную:
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
.\.venv\Scripts\playwright.exe install chromiumБез лимита будут обработаны все обнаруженные URL. Для первого smoke-теста задайте
небольшое значение --max-products:
.\.venv\Scripts\retail-parser.exe crawl `
--stores lemana,maxidom,saturn `
--region novosibirsk `
--region-name "Новосибирск" `
--country-code RU `
--timezone Asia/Novosibirsk `
--output catalog_novosibirsk.jsonl `
--max-products 10Полный прогон и продолжение после остановки:
.\.venv\Scripts\retail-parser.exe crawl --output catalog.jsonl
.\.venv\Scripts\retail-parser.exe crawl --output catalog.jsonl --resume--raw-html добавляет HTML карточки в raw_html. --urls-file urls.txt позволяет
добавить известные карточки, если сайт не перечисляет их в sitemap. --max-pages 0
и --max-products 0 означают отсутствие лимита.
Точечный сбор без sitemap discovery:
.\.venv\Scripts\retail-parser.exe crawl --stores maxidom `
--urls-file examples\product_urls.txt --no-discover --output selected.jsonlРегион задаётся в .env или CLI:
REGION=novosibirsk
REGION_NAME=Новосибирск
COUNTRY_CODE=RU
TIMEZONE=Asia/Novosibirsk
LOCALE=ru-RU
STORE_REGION_CODES_JSON={"saturn":"nsk"}
STORE_BASE_URLS_JSON={"lemana":"https://example-region.lemanapro.ru"}REGION — идентификатор результата, а STORE_REGION_CODES_JSON содержит реальные
коды сайтов. Если магазин выбирает город cookies/API, укажите его cookies в
LEMANA_COOKIES_JSON, MAXIDOM_COOKIES_JSON или SATURN_COOKIES_JSON. Если регион
определяется IP, используйте соответствующий proxy и PROXY_REQUIRE_REGION=true.
Система всегда записывает выбранный профиль в region_code, region_name,
country_code и source_region_*. Подробности: docs/REGIONS.md.
Пример находится в examples/input_data.csv:
.\.venv\Scripts\retail-parser.exe check-input examples\input_data.csv
.\.venv\Scripts\retail-parser.exe run examples\input_data.csv `
--region novosibirsk `
--region-name "Новосибирск" `
--output output_data.csvПри противоречии веса, объёма, размера, цвета, серии или исполнения кандидат не
получит exact. Если доказательств недостаточно, используется partial_match.
Результат хранит цену, URL, решение, confidence, причину, сайт, регион и время по
каждому магазину.
Одна JSONL-строка — один regional product snapshot. Ключевые поля:
store,source_site,source_url;region_code,region_name,country_code,retrieved_at,fetch_method;observed_region,region_verified,region_evidence;title,sku,brand,description,category;price,old_price,currency,available,availability_text,unit;images,breadcrumbs,specifications,identifiers,offers;field_sources,raw_metadata, опциональныйraw_html,error.
Схема и правила snapshot-данных: docs/DATA_MODEL.md.
Наследуйте StoreAdapter, реализуйте поиск/разбор и зарегистрируйте класс:
from retail_matcher.stores import register_store
from retail_matcher.stores.base import StoreAdapter
@register_store
class NewStore(StoreAdapter):
name = "new_store"
default_base_url = "https://shop.example"
product_path_markers = ("/product/",)
@property
def cookies(self):
return {}
def search_url(self, query: str) -> str:
return f"{self.base_url}/search?q={self.quote(query)}"
def parse_search(self, html: str):
return []Затем задайте STORE_PLUGINS=my_package.new_store и проверьте retail-parser stores.
Полное руководство: docs/ADAPTERS.md.
PROXY_PROVIDER поддерживает none, free, custom, Webshare, Bright Data,
Oxylabs, Decodo, Proxy6, SpaceProxy, Proxy-Seller, MobileProxy.Space, Proxys.io,
Proxy.Market и AstroProxy. Реквизиты хранятся только в локальном .env.
.\.venv\Scripts\retail-parser.exe validate-proxiesДля регионального фильтра:
PROXY_REQUIRE_REGION=true
PROXY_REGION_TERMS=novosibirsk,новосибирск,новосибирскаяПубличные бесплатные proxy нестабильны и не подходят для секретов. Качественный residential/mobile endpoint часто необходим для региональной цены и защищённых сайтов.
.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\python.exe -m ruff check src tests
.\.venv\Scripts\python.exe -m buildGitHub Actions запускает тесты на Python 3.10–3.13 и отдельную сборку пакета.
«Полный каталог» означает все карточки, обнаруженные через доступные sitemap, категории и явно переданные URL. Скрытые от навигации или авторизованных пользователей страницы невозможно гарантированно обнаружить без документированного feed/API. Разметка, региональные механизмы и условия сайтов меняются независимо от проекта.
Соблюдайте законодательство, robots/условия сайтов и разумные задержки. Не собирайте персональные данные и не создавайте чрезмерную нагрузку. CAPTCHA не обходится незаконными сервисами.
MIT License. Правила участия — CONTRIBUTING.md, безопасность — SECURITY.md, миграция с 1.x — docs/MIGRATION.md.