★84 звёзд на GitHub и продолжает расти. Yozh Crawler + Scraper — бесплатный, опенсорсный и создаётся публично — поставьте нам звезду, если он заслужил место в вашем стеке.
Заливайте любую публичную страницу или весь сайт в своё хранилище как чистый JSON: вакансии, новости, отзывы, каталоги, публичные профили. Yozh берёт на себя селекторы, анти-бот, ретраи и прокси — вашим загрузчикам остаётся лишь дописывать в Snowflake, BigQuery или Postgres.
Самописные скрейперы съедают 90% времени аналитики и отдают грязные данные
«Небольшой Python-скрипт» превращается в месяцы кручения куки, ротации прокси, починки селекторов, очередей ретраев и подъёмов в 3 часа ночи, потому что источник переименовал класс. Команда данных тратит квартал на перестройку лесов вместо создания дашбордов. Мы даём четыре части, которые каждая команда пересобирает с нуля, — из коробки.
Если после редизайна источника в вашем хранилище больше null, чем строк, — это для вас.
Хрупкие самописные скрейперы гниют за квартал
Проблема. Скрипт на Python «на выходные» превращается в хрупкий внутренний движок: тут очередь, там слой ретраев, никакой наблюдаемости, CSS-селектор, который ломается при каждом редизайне источника. Команда владеет инфраструктурой, которую никогда не хотела писать.
Как это решает Yozh Scraper. Готовый к проду движок: параллельный пакетный исполнитель, автоматические ретраи с экспоненциальной задержкой, структурированные коды ошибок и LLM-самовосстановление, которое регенерирует сломанные селекторы из живого DOM. Один docker compose up заменяет месяцы клея-кода.
самовосстановление LLM
Пакеты + повторы
Структурированные ошибки
HTML-каша на каждом источнике
Проблема. Каждый сайт отдаёт свою уникальную мешанину вложенных div'ов, недокументированных JSON-блоков и несогласованных форматов дат. Вашим загрузчикам нужен шаг нормализации перед хранилищем — и именно он ломается первым при каждом редизайне источника.
Как это решает Yozh Scraper. Встроенные пресеты возвращают одинаковую структуру JSON для всех источников — те же ключи, ISO-даты, нормализованные по локали валюты. Свои источники? POST /api/v1/presets/generate с одним примером URL — LLM определит схему и напишет селекторы. Ложится прямо в COPY ... FROM stdin.
Единая структура JSON
Даты в ISO
Пресеты от LLM
Борьба с анти-ботом съедает спринт
Проблема. Датацентровые прокси выгорают за одну сессию, стены CAPTCHA блокируют краулинг на середине задачи, отпечатки TLS вычисляют headless-браузеры за секунды. Дата-инженеры вместо дашбордов разбирают блокировки. Счета за прокси взрываются, а объём стоит на месте.
Как это решает Yozh Scraper. Нативная интеграция с CyberYozh App Proxy через CYBERYOZH_API_KEY — 5 типов прокси (резидентные ротируемые/статичные, мобильные 4G/5G, датацентровые, ISP) в 250 странах. Стелс-сборка Chromium с «прогретым» отпечатком автоматически совпадает с происхождением прокси. Большинство сценариев вообще не видят CAPTCHA.
5 типов прокси
250 кодов стран
Прогретый отпечаток
Оркестрация краулинга на коленке
Проблема. «Обойди этот сайт, соскрейпь каждую страницу товара, следи за новыми URL» — это одна логическая задача, но в коде это очередь, таблица дедупликации, правила области, лимиты RPS, двухэтапная отмена. Самописное, оно ломается на ретраях и тихо перескрейпивает один и тот же URL.
Как это решает Yozh Scraper. Yozh Crawler обходит сайт на стороне сервера, дедуплицирует по SHA1-хешам на задачу, отдаёт новые URL потоком по SSE и на каждом совпадении сцепляется со скрейпером. Двухэтапная отмена (мягкая → жёсткая). Заливайте поток прямо в Airflow / dbt / cron — оркестрация остаётся в инструментах, которыми вы уже пользуетесь.
SSE-стриминг
Дедупликация по задаче
Airflow / dbt / cron
Как это работает
От сырой веб-страницы до строки в хранилище — за 3 шага
Один эндпоинт для извлечения, одна структура для загрузки. Подключите Yozh прямо к своему загрузчику, оркестратору, хранилищу — промежуточный слой не нужен.
1Поднимите движок
Клонируйте репозиторий и docker compose up. Скрейпер на :8000, краулер на :8001. Без SaaS-аккаунта, без мастера API-ключей — работает в вашем VPC.
# one-time setup
git clone
github.com/CyberYozh-data/yozh-scraper
cd yozh-scraper
docker compose up -d
2Пакетно соскрейпьте список URL
Отправьте POST-пакет URL (до 200 за вызов). Воркеры работают параллельно, ретраи и прокси — на стороне сервера. Одинаковая структура JSON для всех источников.
Результаты идут потоком JSON-строк. Прогоните через jq в COPY ... FROM stdin на Postgres или загрузите напрямую клиентом Snowflake / BigQuery. Ноль промежуточного ПО.
# postgres example
curl :8000/api/v1/scrape/batch
-d @urls.json
| jq -c '.results[]'
| psql -c "COPY raw FROM stdin"
Живой пример
Что вы получаете на выходе — одна структура для каждого маркетплейса
Выберите пресет, чтобы увидеть, как выглядит ответ. Набор полей зависит от источника, но структура запроса одинакова.
Рецепты
Как команды данных подключают это — по 10 строк на каждый
Три конкретных пайплайна от страницы до хранилища, готовых вставить. Yozh занимается скрейпингом — ваш оркестратор занимается расписанием.
1Ежедневный снимок → Postgres
Cron берёт список URL, пакетно скрейпит, льёт JSON-строки прямо в staging-таблицу. Дальше их подхватывает dbt.
# crontab: every day at 06:00
0 6 * * * /usr/local/bin/snapshot.sh# snapshot.shcurl -s :8000/api/v1/scrape/batch
-d "@urls.json"
| jq -c '.results[]'
| psql -c "COPY raw_scrape FROM stdin"# dbt build runs next in Airflow DAGdbt build --select staging.raw_scrape+
200 URLs на пакетCOPY FROM stdinваш cron / Airflow
2Разведочный краулинг → BigQuery
Краульте сайт, отдавая новые URL по мере обнаружения. Дедуплицируйте относительно вчерашних, скрейпьте только дельты, вставляйте строки в BigQuery по мере поступления.
SSE-стримингдедупликация по задаче (SHA1)вставка только изменений
3Поток новостей → Kafka
Краульте и скрейпьте новостные источники, публикуйте каждую статью как событие Kafka. Потребители ниже по потоку (дашборды, модели тональности, алертинг) подписываются по топикам.
цепочка сбор + публикацияKafka-продюсертопик на источник
FAQ
Частые вопросы про скрейпинг в хранилище
Какие источники можно скрейпить?
Любую публичную страницу. Встроенные пресеты покрывают самые высоконагруженные — маркетплейсы, поисковики, YouTube, профили LinkedIn (с сессиями). Для своих источников вызовите POST /api/v1/presets/generate с одним примером URL — LLM определит схему и напишет селекторы, и за секунды вы получите переиспользуемый пресет. Для разовых страниц POST /scrape/page с явной схемой extract: {...} работает вообще без пресета. Robots.txt соблюдается по умолчанию; уважайте его для источников, которыми не владеете.
Как загрузить данные в Snowflake / BigQuery / Postgres?
Скрейпер возвращает JSON-строки на каждый пакет и SSE-поток на каждый краулинг. Заливайте прямо в загрузчик хранилища: jq -c '.results[]' | psql -c "COPY raw FROM stdin" для Postgres, bq insert для BigQuery, snowsql --query "PUT ..." + COPY INTO для Snowflake, либо пишите в S3/GCS и дайте существующему Snowpipe / внешней таблице подхватить. Никакого кастомного коннектора — это просто JSON поверх HTTP.
Можно ли запустить это внутри своего VPC?
Да — Yozh self-hosted. docker compose up поднимает два контейнера (скрейпер + краулер) внутри любой сети, которую вы дадите: VPC, on-prem, air-gapped. Никаких «звонков домой», никакой зависимости от SaaS. Исходящий трафик идёт к целям, которые вы скрейпите (и опционально к CyberYozh App Proxy, если включите). Логи, трейсы и метрики остаются там, где вы их разместили — эндпоинт Prometheus на /metrics, структурированные JSON-логи в stdout.
Как работают ретраи, ошибки и наблюдаемость?
У каждого запроса есть бюджет ретраев с экспоненциальной задержкой (настраивается на вызов). Сбои возвращают структурированные коды ошибок — BLOCKED, CAPTCHA, SELECTOR_FAIL, UPSTREAM_TIMEOUT — чтобы ваш загрузчик ветвился по ним, а не парсил строки. Когда селектор ломается после редизайна источника, LLM-самовосстановление регенерирует его на лету (передайте llm: {model: "..."}) и помечает ответ флагом self_heal: true для последующего аудита. Метрики Prometheus по глубине очереди, доле успеха и задержке прокси — из коробки.
Как это вписывается в Airflow / dbt / Temporal?
Yozh занимается скрейпингом; ваш оркестратор — расписанием. Простейший паттерн: Airflow BashOperator (или PythonOperator с requests) вызывает /scrape/batch, льёт результаты в staging-таблицу, затем сцепляет задачу dbt ниже по потоку. Краулинг возвращает SSE-поток — используйте долгоживущую задачу или разбейте её на возобновляемые части через job_id. Отсутствие встроенного планировщика означает отсутствие вендор-лока: используйте то, что уже крутится на вашей дата-платформе.
Открытый код · Лицензия MIT · 84 ★
Готовы заливать веб-данные в своё хранилище?
Один docker compose up, один поток JSON-строк, каждый источник нормализован — прямо в Snowflake, BigQuery, Postgres, Kafka. Бесплатно. Навсегда. Поставьте звезду, если помогло — каждая звезда на счету.
Заменили наш собственный кластер Playwright на Yozh за полдня. MCP-эндпоинт встал прямо в нашего Claude-агента — ноль связующего кода, краулер и скрейпер просто заработали.
Система пресетов — киллер-фича. Передаём имя источника и получаем чистый JSON; самовосстановление даже поймало два изменения вёрстки Amazon раньше нас.
PNPriya NairОсновательScrapeStack
Reddit
Наконец-то опенсорсный скрейпер, для которого прокси и сессии — первоклассные сущности. Гоняем его за логин-стенами партнёрских порталов — сессии живут, результаты стабильны в разных регионах.
DODaniel OseiBackend-инженерLoopfeed
X
Подключил к Cursor через MCP, и теперь мой агент тянет живые веб-данные прямо посреди задачи. Стриминговый обход по SSE — именно то, чего не хватало агентным сценариям.
EKElena KovacИИ-инженерVektor Labs
GitHub
Ушли с платного API скрейпинга ради экономии и готовились к откату по качеству — получили обратное. Self-hosted, без оплаты за запрос, а схема вывода чище, чем та, за которую мы платили.