Парсинг данных из крипто-новостных агрегаторов
Крипто-рынок реагирует на новости быстрее, чем tradfi: от публикации статьи о регуляторных действиях до движения цены — иногда секунды. Для трейдинговых систем, мониторинга рисков или sentiment-анализа нужен структурированный поток новостей с минимальной latency.
Источники и методы получения данных
RSS/Atom фиды (самое надёжное)
CoinDesk, Cointelegraph, The Block, Decrypt — все имеют RSS. Это официальный, стабильный канал:
import Parser from "rss-parser";
const parser = new Parser({
customFields: {
item: [["media:content", "media", { keepArray: false }]],
},
});
const feeds: Record<string, string> = {
coindesk: "https://www.coindesk.com/arc/outboundfeeds/rss/",
cointelegraph: "https://cointelegraph.com/rss",
theblock: "https://www.theblock.co/rss.xml",
decrypt: "https://decrypt.co/feed",
};
async function fetchFeed(source: string, url: string): Promise<NewsItem[]> {
const feed = await parser.parseURL(url);
return feed.items.map((item) => ({
source,
title: item.title ?? "",
url: item.link ?? "",
publishedAt: new Date(item.pubDate ?? ""),
summary: item.contentSnippet ?? "",
guid: item.guid ?? item.link ?? "",
}));
}
Polling каждые 5 минут — разумный баланс между freshness и нагрузкой на источник. Дедупликация по guid.
Official APIs
CryptoPanic API — агрегатор новостей с sentiment scoring:
GET https://cryptopanic.com/api/v1/posts/?auth_token={key}¤cies=BTC,ETH&kind=news
Отдаёт структурированные данные с bullish/bearish голосами сообщества.
Messari API — качественные новости с asset-тегами:
GET https://data.messari.io/api/v1/news?page=1&limit=50
Santiment — новости + on-chain данные + social metrics в одном API.
HTML парсинг (когда API нет)
Для источников без RSS — cheerio (Node.js) или BeautifulSoup (Python). Хрупкий подход: любое изменение разметки ломает парсер. Для критичных источников — мониторинг успешности парсинга и быстрый alert при падении extraction rate.
import * as cheerio from "cheerio";
async function scrapeBlockworks(html: string): Promise<NewsItem[]> {
const $ = cheerio.load(html);
return $("article.post-card").map((_, el) => ({
title: $(el).find("h2.post-title").text().trim(),
url: $(el).find("a").attr("href") ?? "",
publishedAt: new Date($(el).find("time").attr("datetime") ?? ""),
summary: $(el).find("p.excerpt").text().trim(),
})).get();
}
Обработка и хранение
Дедупликация критична — одна новость может появиться в нескольких источниках. Нормализованный URL (удаление UTM параметров) + title similarity (cosine similarity или Levenshtein distance) для обнаружения дублей.
CREATE TABLE news_items (
id BIGSERIAL PRIMARY KEY,
source VARCHAR(50) NOT NULL,
external_id VARCHAR(255) NOT NULL, -- guid от RSS
title TEXT NOT NULL,
url TEXT NOT NULL,
published_at TIMESTAMPTZ NOT NULL,
summary TEXT,
raw_content TEXT,
tags TEXT[], -- ['bitcoin', 'regulation', 'SEC']
UNIQUE (source, external_id)
);
CREATE INDEX idx_news_published ON news_items (published_at DESC);
CREATE INDEX idx_news_tags ON news_items USING GIN (tags);
Asset tagging — определяем какие криптоактивы упомянуты в новости по списку тикеров и названий. Простой regex-based подход даёт 80–90% точности для основных активов.
Что важно в production
Robots.txt и rate limiting: уважать правила источника, не генерировать избыточную нагрузку. Jitter между запросами (не ровные интервалы, это выглядит как бот).
User-Agent: идентифицировать себя корректно. Некоторые источники блокируют headless browser user-agents.
Мониторинг freshness: если последняя новость от источника старше 30 минут — алерт. RSS может зависнуть без явной ошибки.
Реалистичный срок для агрегатора 10–15 источников с API + хранением: 2–3 недели.







