84 звёзд на GitHub и продолжает расти. Yozh Crawler + Scraper — бесплатный, опенсорсный и создаётся публично — поставьте нам звезду, если он заслужил место в вашем стеке.
CyberYozh Data / Сценарии / Веб-парсинг и аналитика
Сценарий · Веб-скрейпинг

Публичные веб-данные, структурированные для SQL

Заливайте любую публичную страницу или весь сайт в своё хранилище как чистый JSON: вакансии, новости, отзывы, каталоги, публичные профили. Yozh берёт на себя селекторы, анти-бот, ретраи и прокси — вашим загрузчикам остаётся лишь дописывать в Snowflake, BigQuery или Postgres.

$curl -s :8000/api/v1/scrape/batch -d @urls.json | jq -c '.results[]' | psql -c "COPY raw FROM stdin"
batch: g2.com/products
Target table
scraped_pages
Batch
200 urls 8 workers 1.0/s
Status
streaming · 247 / 200 rows
Yozh batch /scrape/batch
Pulling URL batch
Stealth fetch + retry
Parsing & normalizing
Emitting JSON-lines
COPY FROM stdin
Заливается в ваш стек
Почему большинство пайплайнов гниёт

Самописные скрейперы съедают 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 для всех источников.

curl 
  localhost:8000/api/v1/scrape/batch 
  -X POST 
  -d '{"urls": ["…", "…"],
       "preset": "auto",
       "concurrency": 8}'
3 Заливайте прямо в хранилище

Результаты идут потоком 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.sh
curl -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 DAG
dbt build --select staging.raw_scrape+
200 URLs на пакет COPY FROM stdin ваш cron / Airflow
2 Разведочный краулинг → BigQuery

Краульте сайт, отдавая новые URL по мере обнаружения. Дедуплицируйте относительно вчерашних, скрейпьте только дельты, вставляйте строки в BigQuery по мере поступления.

# stream discovered URLs over SSE
curl -N :8001/api/v1/crawl/start 
  -d '{"seed_url":"site.com",
       "scope":"same-domain",
       "max_pages":1000}' 
| jq -r 'select(.event=="found") | .url' 
| comm -13 yesterday.txt - 
| bq insert dataset.urls --source_format=NEWLINE_DELIMITED_JSON
SSE-стриминг дедупликация по задаче (SHA1) вставка только изменений
3 Поток новостей → Kafka

Краульте и скрейпьте новостные источники, публикуйте каждую статью как событие Kafka. Потребители ниже по потоку (дашборды, модели тональности, алертинг) подписываются по топикам.

# 1. continuous crawl of source list
curl -N :8001/api/v1/crawl/start 
  -d "@sources.json" 
| jq -c 'select(.event=="scraped") | .result' 
| kcat -P -t news.raw -b kafka:9092

# 2. consumers subscribe downstream
kcat -C -t news.raw | your-pipeline
цепочка сбор + публикация 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. Бесплатно. Навсегда. Поставьте звезду, если помогло — каждая звезда на счету.

Yozh Crawler + Scraper распространяется под лицензией MIT. Используйте. Форкайте. Создавайте.

Нас любят data-команды и AI-разработчики

Что говорят те, кто строит на Yozh

5,0 / 5 · Отзывов: 5
GitHub
Заменили наш собственный кластер Playwright на Yozh за полдня. MCP-эндпоинт встал прямо в нашего Claude-агента — ноль связующего кода, краулер и скрейпер просто заработали.
Marcus Reinhardt Ведущий дата-инженер Northwind Analytics
X
Система пресетов — киллер-фича. Передаём имя источника и получаем чистый JSON; самовосстановление даже поймало два изменения вёрстки Amazon раньше нас.
Priya Nair Основатель ScrapeStack
Reddit
Наконец-то опенсорсный скрейпер, для которого прокси и сессии — первоклассные сущности. Гоняем его за логин-стенами партнёрских порталов — сессии живут, результаты стабильны в разных регионах.
Daniel Osei Backend-инженер Loopfeed
X
Подключил к Cursor через MCP, и теперь мой агент тянет живые веб-данные прямо посреди задачи. Стриминговый обход по SSE — именно то, чего не хватало агентным сценариям.
Elena Kovac ИИ-инженер Vektor Labs
GitHub
Ушли с платного API скрейпинга ради экономии и готовились к откату по качеству — получили обратное. Self-hosted, без оплаты за запрос, а схема вывода чище, чем та, за которую мы платили.
Sofia Almeida Инженерный менеджер Tabbly