Парсинг даних з 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 секунд відносно реальної подіїї на блокчейні.







