Парсинг данных с NFT-маркетплейсов (OpenSea, Blur, Magic Eden)
OpenSea отдаёт данные по API, но rate limit в 2 req/sec на бесплатном tier делает полноценный сбор исторических данных по коллекции неприятным квестом. Blur и Magic Eden — у каждого своя модель: Blur всё ещё во многом строится на недокументированных эндпоинтах, Magic Eden разделён на два несовместимых API (Solana и EVM). Если нужны полные данные о продажах, листингах и floor price в реальном времени — решений «коробкой» почти нет, нужно строить парсер под каждую площадку отдельно.
Архитектура сбора данных
OpenSea: официальный API vs. events endpoint
OpenSea Developer API v2 — единственный официальный путь. Ключевые методы:
-
GET /api/v2/events/collection/{slug}— история событий (sales, listings, transfers) с пагинацией поnextcursor -
GET /api/v2/listings/collection/{slug}/all— активные листинги с ценами -
GET /api/v2/collections/{slug}/stats— floor price, volume, supply
Проблема: events endpoint отдаёт максимум 50 событий за запрос, rate limit не задокументирован явно, но на практике более 2-3 req/sec приводит к 429. Для сбора истории коллекции с 100k+ продажами это недели работы при тупом последовательном запросе.
Оптимизация: параллельные воркеры с backoff, разбивка диапазона событий по occurred_after / occurred_before параметрам. При наличии Pro API ключа лимиты вырастают до 10-20 req/sec — сбор той же истории занимает часы.
Для WebSocket обновлений: OpenSea Stream API на базе Phoenix Channels. Подписка на collection:{slug} даёт realtime события листингов и продаж без поллинга.
from opensea_stream import OpenSeaStreamClient, Network
client = OpenSeaStreamClient(token=API_KEY, network=Network.MAINNET)
client.on_item_sold("collection-slug", lambda event: handle_sale(event))
client.connect()
Blur: работа с недокументированным API
Blur не предоставляет публичного API. Данные доступны через:
-
Blur GraphQL (
https://core-api.prod.blur.io/graphql) — не документирован, но стабилен. Через DevTools браузера легко снять запросы к коллекциям, листингам и бидам. - Reservoir Protocol — агрегатор ликвидности, который индексирует Blur события on-chain. Предоставляет единый API для данных со всех основных маркетплейсов включая Blur.
Reservoir — наиболее надёжный путь для Blur данных. API хорошо задокументирован, есть SDK:
import { createClient } from "@reservoir0x/reservoir-sdk"
const client = createClient({ apiBase: "https://api.reservoir.tools", apiKey: KEY })
const sales = await client.getSales({ collection: "0x...", limit: 100 })
Magic Eden: EVM и Solana разрыв
Magic Eden имеет два несовместимых API:
| API | Блокчейны | Endpoint |
|---|---|---|
| Solana API v2 | Solana | api-mainnet.magiceden.dev/v2/ |
| Developer API | Ethereum, Polygon, Base | api-mainnet.magiceden.dev/v3/rtp/ |
Developer API (EVM) основан на Reservoir под капотом — те же структуры данных, те же принципы. Solana API v2 — отдельная история: GET /collections/{symbol}/activities для событий, пагинация через offset.
Solana-данные о продажах хранятся в transaction logs. Для полной истории, не зависящей от API Magic Eden, — прямой парсинг on-chain через Helius или QuickNode с фильтрацией по program ID Magic Eden (MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8).
Хранение и обработка данных
Схема для sales данных в PostgreSQL:
CREATE TABLE nft_sales (
id BIGSERIAL PRIMARY KEY,
blockchain VARCHAR(20) NOT NULL,
marketplace VARCHAR(20) NOT NULL,
contract_address VARCHAR(42),
token_id VARCHAR(78),
seller_address VARCHAR(42),
buyer_address VARCHAR(42),
price_raw NUMERIC(38,0),
price_usd DECIMAL(20,6),
currency_symbol VARCHAR(10),
transaction_hash VARCHAR(66) UNIQUE,
block_number BIGINT,
event_timestamp TIMESTAMPTZ NOT NULL,
raw_data JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX ON nft_sales (contract_address, event_timestamp DESC);
CREATE INDEX ON nft_sales (marketplace, event_timestamp DESC);
JSONB поле raw_data сохраняет оригинальный ответ API — пригодится при изменении структуры данных маркетплейса. Конвертация цены в USD: в реальном времени через CoinGecko/Coingecko API или ретроспективно через OHLCV данные.
Anti-detection для web scraping
Если маркетплейс не даёт API и нужен browser scraping (редкий случай, но бывает для агрегаторов): Playwright + rotating residential proxies + stealth plugin (playwright-extra + puppeteer-extra-plugin-stealth). Без этого headless Chrome детектируется по navigator.webdriver, canvas fingerprint и timing-паттернам.
Для rate limit менеджмента — token bucket алгоритм с Redis как distributed rate limiter если запросы идут с нескольких машин.
Процесс и сроки
День 1: Анализ целевых маркетплейсов, получение API ключей, разработка схемы хранения данных, реализация базовых HTTP клиентов с retry/backoff.
День 2-3: Воркеры для исторического сбора, WebSocket интеграция для realtime, нормализация данных между форматами разных площадок, документация и базовый мониторинг.
Результат: система, которая собирает полную историю и держит актуальные данные с задержкой 30-60 секунд относительно реального события на блокчейне.







