# omni-parse Один парсер под любую тему: Reddit, форумы, поисковики, X/Twitter, карточки товаров и платные search-API — в одну SQLite-базу с FTS5, дедупом и рейтингом. Ставится без ключей. Платные провайдеры включаются сами, если в окружении есть ключ. ## Что умеет | Провайдер | Что тянет | Ключ | |---|---|---| | `reddit` | поиск по постам и комментариям через api.pullpush.io (архив Reddit) + публичный json как запас | нет | | `forums` | Discourse (9 инстансов), Hacker News (Algolia), Lobsters, XenForo, веб-версии Telegram-каналов | нет | | `ddg` | html-выдача DuckDuckGo | нет | | `bing` | html-выдача Bing, ссылки раскодируются из `ck/a?...u=a1` | нет | | `mojeek` | html Mojeek (свой индекс, без капчи) | нет | | `x` | без платного API: oembed по URL твита, syndication-таймлайн профиля, поиск твитов через ddg/bing/mojeek | нет | | `tavily` | Tavily search | `TAVILY_API_KEY` | | `exa` | Exa search + текст страниц | `EXA_API_KEY` | | `you` | You.com search | `YOU_API_KEY` | | `firecrawl` | Firecrawl search | `FIRECRAWL_API_KEY` | | `cards` | карточки товаров: JSON-LD Product/Offer, OpenGraph, microdata, цена/валюта/наличие | нет | | `treg` | treg-поиск | `TREG_TOKEN` | `python -m omni providers` печатает, что реально поднялось в этом окружении. ## Установка ```bash pip install -r requirements.txt cp .env.example .env # ключи по желанию, ни один не обязателен ``` ## Быстрый старт ```bash # что доступно python -m omni providers # поиск по одной теме в четырёх бесплатных источниках python -m omni search "scraping twitter without api" --providers reddit,forums,ddg,bing --limit 12 --show 10 # прогон по списку тем из themes.txt (по теме на строку) python -m omni fanout --providers reddit,forums,ddg,bing --limit 10 # топ базы, статистика, поиск по своей базе python -m omni top --limit 20 python -m omni stats python -m omni find "proxy" # карточки товаров по URL python -m omni cards https://example.com/product # выгрузка python -m omni export --format jsonl --out data/dump.jsonl ``` ## Как устроено - `omni/net.py` — лестница транспорта: httpx → curl_cffi (подмена TLS-фингерпринта) → прокси из env. Троттлинг по хосту, лимит байт, пометка блокировок. - `omni/model.py` — единая схема записи: провайдер, тип, url, заголовок, текст, автор, дата, теги, цена, счёт, simhash. - `omni/filter.py` — релевантность: запрос должен быть покрыт текстом (≥60% терминов) и хотя бы один термин — в заголовке. Для русского сравнивает по 5-символьному префиксу, иначе морфология убивает совпадения. - `omni/store.py` — SQLite WAL + FTS5, таблицы `items`, `bands`, `runs`. Дедуп: simhash по шинглам, сравнение по Хэммингу ≤3 по бакетам. - `omni/rank.py` — вес провайдера, свежесть, наличие цены, вовлечение. - `omni/providers/` — по файлу на семейство источников, реестр в `__init__.py`. ## Реальные прогоны ``` python -m omni search "scraping twitter without api" --providers reddit,forums,ddg,bing bing 10 ok | ddg 10 ok | forums 10 ok | reddit 8 ok собрано 38, новых 31, дублей 7 python -m omni fanout # 8 тем из themes.txt итого новых 200, дублей 5 python -m omni stats записей 266 | прогонов 56 (ok 37) ddg=93 bing=85 forums=56 reddit=32 ``` ## Ограничения - Reddit напрямую с серверных IP отдаёт 403 — используется архив pullpush; свежие посты (последние часы) в архиве могут отсутствовать. - X/Twitter без токена: доступны только публичные встраивания и таймлайн профиля, полноценного полнотекстового поиска нет. - mojeek отдаёт пустую страницу при агрессивном троттлинге — провайдер помечается, остальные работают. - `cards` не обходит защиту от парсинга: если страница рендерится JS, разметки в html не будет. ## Лицензия MIT.