CoinMarketCap является стандартным справочником по рыночным данным криптовалют: он отслеживает актуальные цены, рыночную капитализацию, объём торгов и рейтинги тысяч монет, обновляя эти данные практически в реальном времени. Эта публичная таблица лежит в основе ценовых дашбордов, трекеров портфелей и рыночных исследований, поэтому так много людей хотят иметь её чистую структурированную копию.

Это руководство показывает, как парсить цены криптовалют с CoinMarketCap с помощью Python. Вы создадите небольшой работающий парсер, который получает отрендеренную страницу листинга через Crawling API, извлекает нужные поля с помощью BeautifulSoup и записывает чистую запись для каждой монеты. Всё руководство ограничено публичными рыночными данными: название монеты, символ, цена, рыночная капитализация, изменение за 24 ч и объём. Раздел о законности в конце не является шаблоном, а CoinMarketCap предоставляет официальный API, поэтому прочитайте оба раздела перед тем, как запускать скрипт на реальных объёмах.

Что вы создадите

Скрипт на Python, который получает публичную главную страницу CoinMarketCap, извлекает отрендеренный HTML через Crawling API и выбирает структурированную запись для ведущих монет в таблице. Для каждой монеты извлекаются следующие поля:

  • Name полное название монеты, например «Bitcoin».
  • Symbol тикер-символ, например «BTC».
  • Price текущая цена в USD.
  • Market cap общая рыночная капитализация, показанная в строке.
  • 24h change процентное изменение за последние 24 часа.
  • Volume объём торгов за 24 часа.

Почему обычный запрос не работает на CoinMarketCap

Если вы запрашиваете CoinMarketCap обычным HTTP-клиентом, вы редко получаете чистую таблицу цен, которую видите в браузере. Два фактора работают против вас. Во-первых, CoinMarketCap рендерит большую часть своей рыночной таблицы на стороне клиента: начальный HTML является тонкой оболочкой, а строки заполняются только после выполнения JavaScript страницы. Во-вторых, сайт защищён системами защиты от ботов, такими как Cloudflare, поэтому IP-адреса дата-центров и паттерны запросов, не похожие на реальный браузер, блокируются или ограничиваются по скорости до того, как они достигают отрендеренной таблицы.

Таким образом, наивный вызов requests.get() обычно возвращает либо пустую оболочку, либо страницу проверки вместо данных о монетах. Рабочий парсер CoinMarketCap требует двух вещей одновременно: браузера, рендерящего страницу, и IP-адреса, который сайт воспринимает как обычного посетителя.

Можно собрать это самостоятельно с headless-браузером и пулом ротирующихся резидентных прокси, но объединение этих компонентов и поддержание их в рабочем состоянии составляет основную часть работы. Crawling API объединяет сложные части в один вызов: вы передаёте ему URL CoinMarketCap с JavaScript-токеном, он рендерит страницу через доверенный IP и возвращает готовый HTML для парсинга. Если вы предпочитаете маршрутизировать собственные запросы через ротирующийся пул, Smart AI Proxy предоставляет ту же ротацию резидентных IP в качестве подключаемого прокси-эндпоинта.

Зачем нужен JS-токен

Crawlbase предлагает два типа токенов. Обычный токен получает статический HTML; JavaScript (JS) токен сначала рендерит страницу в реальном браузере. Рыночная таблица CoinMarketCap рендерится на стороне клиента, поэтому здесь вам нужен JS-токен. Обычный токен, как правило, возвращает ту же тонкую оболочку, что и обычный запрос, с отсутствующими строками для парсинга.

Предварительные требования

Прежде чем писать код, необходимо подготовить несколько вещей. Ни одна из них не занимает много времени.

Базовые знания Python. Вы должны уметь писать и запускать скрипты на Python, а также устанавливать пакеты с помощью pip. Если парсинг HTML для вас нов, наше руководство о том, как использовать BeautifulSoup в Python, охватывает базовые принципы работы с селекторами, которые предполагает этот учебник.

Python версии 3.8 или выше. Проверьте свою версию командой python --version. Если его нет, установите с python.org или через дистрибутив, например Anaconda.

Аккаунт Crawlbase и JS-токен. Зарегистрируйтесь, откройте панель управления и скопируйте JavaScript (JS) токен со страницы документации аккаунта. Относитесь к токену как к паролю: он аутентифицирует ваши запросы, поэтому не добавляйте его в систему контроля версий.

Настройка проекта

Создайте виртуальное окружение, чтобы зависимости проекта были изолированы, затем установите две библиотеки, необходимые парсеру.

bash
python --version

python -m venv cmc_env
source cmc_env/bin/activate

pip install crawlbase beautifulsoup4

На Windows активируйте окружение командой cmc_env\Scripts\activate вместо строки с source. Две зависимости выполняют основную работу: crawlbase является официальным клиентом для Crawling API, а beautifulsoup4 парсит возвращаемый HTML, позволяя извлекать отдельные поля по CSS-селектору.

Шаг 1: получение отрендеренной страницы

Начните с получения готовой страницы. Импортируйте класс CrawlingAPI, инициализируйте его с помощью JS-токена и запросите URL CoinMarketCap. Проверка кода статуса перед парсингом гарантирует, что сбои будут заметны, а не тихи.

python
from crawlbase import CrawlingAPI

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"})

def crawl(page_url):
    options = {"ajax_wait": "true", "page_wait": 5000}
    response = api.get(page_url, options)
    if response["status_code"] == 200:
        return response["body"].decode("latin1")
    print(f"Request failed: {response['status_code']}")
    return None

if __name__ == "__main__":
    page_url = "https://coinmarketcap.com/"
    html = crawl(page_url)
    print(html[:500] if html else "No HTML returned")

Два параметра ожидания важны для цели с клиентским рендерингом: ajax_wait указывает API дождаться завершения загрузки асинхронного контента, а page_wait ожидает фиксированное количество миллисекунд после загрузки, чтобы строки таблицы с поздним рендерингом появились до захвата страницы. Пять секунд является разумной отправной точкой; увеличьте значение, если таблица возвращается пустой. CoinMarketCap отправляет страницы в различных кодировках, поэтому декодирование через latin1 позволяет избежать ошибок байтов, которые может выбросить строгое декодирование в UTF-8. Запустите скрипт, и вы должны увидеть реальную рыночную разметку, а не тонкую оболочку, возвращаемую обычным запросом.

Crawlbase Crawling API

Таблица CoinMarketCap требует отрендеренной страницы через доверенный IP за один вызов. Crawling API принимает JS-токен, запускает страницу в реальном браузере, ротирует резидентные IP на стороне сервера и передаёт готовый HTML, чтобы вы не запускали headless-флот браузеров и пул прокси самостоятельно. Сначала направьте его на публичную главную страницу в рамках бесплатного уровня.

Шаг 2: парсинг полей монеты с помощью BeautifulSoup

Имея отрендеренный HTML, загрузите его в BeautifulSoup и пройдитесь по строкам таблицы. CoinMarketCap располагает каждую монету в виде строки основной рыночной таблицы, с названием и символом в ячейке монеты и числовыми полями в столбцах справа. Оберните извлечение каждой строки в блок try/except, чтобы одно отсутствующее поле не прерывало весь прогон.

python
from bs4 import BeautifulSoup

def text_of(row, selector):
    el = row.select_one(selector)
    return el.get_text(strip=True) if el else None

def scrape_coins(html, limit=10):
    soup = BeautifulSoup(html, "html.parser")
    rows = soup.select("table tbody tr")[:limit]

    coins = []
    for row in rows:
        try:
            cells = row.select("td")
            coins.append({
                "name": text_of(row, "p.coin-item-name"),
                "symbol": text_of(row, "p.coin-item-symbol"),
                "price": cells[3].get_text(strip=True),
                "change_24h": cells[4].get_text(strip=True),
                "market_cap": cells[7].get_text(strip=True),
                "volume_24h": cells[8].get_text(strip=True),
            })
        except (IndexError, AttributeError) as e:
            print("Skipping a row due to error:", e)
    return coins

Название и символ имеют стабильные, удобочитаемые хуки классов, p.coin-item-name и p.coin-item-symbol, поэтому вы обращаетесь к ним напрямую. Числовые столбцы (цена, изменение за 24 ч, рыночная капитализация и объём) извлекаются позиционно из ячеек td строки, поскольку ценовая ячейка CoinMarketCap содержит хешированное, часто меняющееся имя класса, которое небезопасно жёстко кодировать. Вспомогательная функция text_of возвращает None вместо исключения при отсутствии элемента, а блок try/except защищает от строки с отличной раскладкой столбцов, чтобы одна странная строка не прерывала прогон.

Селекторы дрейфуют

Разметка CoinMarketCap, особенно хешированные имена классов, изменяется без предупреждения. Рассматривайте приведённые выше селекторы и индексы столбцов как начальный шаблон, а не как контракт. Когда поле возвращается неверным или пустым, щёлкните правой кнопкой мыши по ячейке в инструментах разработчика браузера, проверьте живую структуру и скорректируйте селектор или индекс. Периодическое обслуживание селекторов нормально для любого рабочего парсера, это не признак поломки.

Шаг 3: объединение всего вместе

Теперь объедините получение и парсинг в один запускаемый скрипт. Получите отрендеренный HTML, передайте его парсеру и выведите структурированные записи в формате JSON.

python
import json
from crawlbase import CrawlingAPI
from bs4 import BeautifulSoup

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"})

def crawl(page_url):
    options = {"ajax_wait": "true", "page_wait": 5000}
    response = api.get(page_url, options)
    if response["status_code"] == 200:
        return response["body"].decode("latin1")
    print(f"Request failed: {response['status_code']}")
    return None

def text_of(row, selector):
    el = row.select_one(selector)
    return el.get_text(strip=True) if el else None

def scrape_coins(html, limit=10):
    soup = BeautifulSoup(html, "html.parser")
    rows = soup.select("table tbody tr")[:limit]

    coins = []
    for row in rows:
        try:
            cells = row.select("td")
            coins.append({
                "name": text_of(row, "p.coin-item-name"),
                "symbol": text_of(row, "p.coin-item-symbol"),
                "price": cells[3].get_text(strip=True),
                "change_24h": cells[4].get_text(strip=True),
                "market_cap": cells[7].get_text(strip=True),
                "volume_24h": cells[8].get_text(strip=True),
            })
        except (IndexError, AttributeError) as e:
            print("Skipping a row due to error:", e)
    return coins

def main():
    html = crawl("https://coinmarketcap.com/")
    if not html:
        return
    data = scrape_coins(html)
    print(json.dumps(data, indent=2))

if __name__ == "__main__":
    main()

Как выглядит вывод

Запустите полный скрипт командой python scraper.py, и вы получите чистый список структурированных записей, готовых для записи в JSON, CSV или базу данных. Точные цены будут отличаться от приведённого ниже примера, поскольку рынок постоянно движется.

json
[
  {
    "name": "Bitcoin",
    "symbol": "BTC",
    "price": "$92,477.64",
    "change_24h": "2.14%",
    "market_cap": "$1.83T",
    "volume_24h": "$38.20B"
  },
  {
    "name": "Ethereum",
    "symbol": "ETH",
    "price": "$1,744.77",
    "change_24h": "1.06%",
    "market_cap": "$210.6B",
    "volume_24h": "$14.95B"
  }
]

Экспорт в CSV и JSON

Вывод JSON в консоль подходит для демонстрации, но обычно вам нужны данные на диске для хранения или последующего анализа. Записи уже являются списком плоских словарей, поэтому запись в оба формата занимает несколько строк. Повторно используйте функции crawl и scrape_coins из полного скрипта выше.

python
import csv
import json

html = crawl("https://coinmarketcap.com/")
coins = scrape_coins(html)
fields = ["name", "symbol", "price", "change_24h", "market_cap", "volume_24h"]

with open("crypto_prices.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=fields)
    writer.writeheader()
    writer.writerows(coins)

with open("crypto_prices.json", "w") as f:
    json.dump(coins, f, indent=2)

print(f"Saved {len(coins)} coins to crypto_prices.csv and crypto_prices.json")

После этого CSV сразу открывается в электронной таблице или в pandas DataFrame для анализа, а файл JSON легко загружается в нижестоящий сервис. Если вам нужна живая лента, а не единовременный снимок, запустите скрипт по расписанию с определённым интервалом и добавляйте каждую выборку в датированный файл.

Масштабирование на большее количество монет и страниц

Главная страница содержит ведущие монеты, но CoinMarketCap разбивает полный рейтинг на страницы. Структура работы не меняется: структура листинга одинакова на каждой странице, поэтому уже написанный парсер продолжает работать. Перебирайте пронумерованные страницы, получайте каждую через Crawling API и собирайте строки.

python
all_coins = []

for page in range(1, 4):  # first three pages of the ranking
    url = f"https://coinmarketcap.com/?page={page}"
    html = crawl(url)
    if html:
        all_coins.extend(scrape_coins(html, limit=100))

print(f"Collected {len(all_coins)} coins across pages")

Если вам нужен автономный запуск в масштабе, поставьте URL страниц в очередь через асинхронный Crawler вместо синхронного цикла, чтобы отправить весь набор страниц и собирать результаты по мере их завершения. Подробнее о целях с интенсивным рендерингом смотрите наше руководство по парсингу JavaScript-страниц с Python, где глубже рассматривается паттерн ожидания и рендеринга, на котором основан этот парсер.

Как оставаться незаблокированным

Даже при обработанном рендеринге CoinMarketCap отслеживает трафик, похожий на парсер. Несколько привычек помогают сохранить работоспособность прогона, и они применимы к любой защищённой цели с интенсивным использованием JavaScript.

  • Соблюдайте темп запросов. Получение каждой страницы в жёстком цикле быстрее всего приведёт к ограничению скорости. Распределяйте запросы, и для живой ленты каждые несколько минут достаточно, а не интенсивный темп.
  • Используйте ротацию. Пул резидентных IP распределяет запросы по множеству адресов реальных пользователей, чтобы ни один из них не превысил ограничение скорости. Crawling API делает это за вас; если вы строите собственный стек, это та часть, которую нужно сделать правильно.
  • Следите за кодами статуса. Прогон, начавший возвращать проверки или ошибки, сигнализирует, что текущего темпа или уровня IP уже недостаточно. Воспринимайте это как сигнал отступить, а не как шум, который можно игнорировать.

Для более широкой стратегии смотрите как парсить сайты без блокировок и более глубокое погружение в тему как обходить CAPTCHA при веб-скрейпинге.

Законно ли парсить CoinMarketCap?

Допустимость парсинга CoinMarketCap зависит от условий использования сайта, вашей юрисдикции и того, что вы делаете с данными. CoinMarketCap публикует Условия использования и robots.txt, и оба документа устанавливают границы для автоматического доступа. Ни один из кодов здесь не меняет этого: он просто делает техническую часть работающей. Прочитайте эти документы и рассматривайте их как ограничение того, что вы собираете и как часто запрашиваете, особенно перед любым коммерческим проектом.

Сохраняйте узкий охват. Рыночная таблица, рассматриваемая здесь, является действительно публичными данными: название монеты, символ, цена, рыночная капитализация, изменение за 24 ч и объём, которые видны без аккаунта. Это граница, которая делает работу обоснованной. То, что это руководство не охватывает, не менее важно: всё за логином, данные аккаунта или списка наблюдения, привязанные к пользователю, персональную информацию и защищённые авторским правом медиа, которые вы будете распространять повторно, выходят за рамки данной темы. Не обходите аутентификацию для доступа к данным, которые публичная таблица ещё не отображает.

Ещё один момент, специфичный для этой цели: CoinMarketCap предоставляет официальный API. Для производственных систем, коммерческого использования или масштабных запросов этот официальный API является правильным путём, поскольку даёт вам поддерживаемый контракт, предсказуемые ограничения скорости и данные, на использование которых у вас есть явная лицензия. Парсинг публичного сайта подходит для обучения, прототипирования и небольших задач с публичными данными, а не для бизнеса, которому нужна гарантированная доступность и чёткие права использования. При сомнениях предпочитайте официальный API.

Итоги

Ключевые выводы

  • Рыночная таблица рендерится на стороне клиента и защищена. Обычный запрос возвращает тонкую оболочку или проверку, поэтому необходимо рендерить страницу через доверенный IP до парсинга.
  • Один вызов делает оба. Crawling API с JS-токеном рендерит страницу и ротирует резидентные IP на стороне сервера; ajax_wait и page_wait управляют временем ожидания загрузки строк.
  • Комбинируйте стратегии селекторов. Фиксируйте название и символ на p.coin-item-name и p.coin-item-symbol, извлекайте числовые столбцы позиционно и ожидайте дрейфа хешированных имён классов.
  • Экспортируйте и масштабируйте чисто. Плоские словари записываются прямо в CSV или JSON, и один и тот же парсер работает для разбитых на страницы рейтинговых страниц.
  • Предпочитайте официальный API для производства. Оставайтесь в рамках публичных рыночных данных, соблюдайте ToS и robots.txt и используйте официальный API CoinMarketCap для коммерческого или масштабного использования.

Часто задаваемые вопросы

Почему обычный запрос не возвращает цены криптовалют с CoinMarketCap?

По двум причинам. Во-первых, CoinMarketCap рендерит большую часть своей рыночной таблицы на стороне клиента с помощью JavaScript, поэтому сырой HTML является тонкой оболочкой, которая заполняется только после выполнения скриптов страницы. Во-вторых, сайт защищён системами защиты от ботов, такими как Cloudflare, поэтому автоматизированный трафик с IP-адресов дата-центров часто блокируется или ограничивается по скорости до достижения данных. Рендеринг страницы с JS-токеном Crawling API через доверенный IP позволяет строкам появляться.

Нужен ли мне обычный токен или JS-токен для CoinMarketCap?

JS-токен. Обычный токен получает статический HTML, который на CoinMarketCap, как правило, является той же тонкой оболочкой, что и обычный запрос. JS-токен рендерит страницу в реальном браузере перед возвратом HTML, поэтому строки таблицы, включая цену, рыночную капитализацию и объём, присутствуют к моменту, когда BeautifulSoup их парсит.

Как часто можно парсить цены криптовалют?

Для живой ленты получение каждые несколько минут обычно безопасно и позволяет оставаться значительно ниже любого порога скорости. Интенсивный запрос сайта в жёстком цикле является самым быстрым способом получить ограничение скорости или проверку. Маршрутизируйте через ротирующиеся резидентные IP, следите за кодами статуса и откатывайтесь при появлении проверок. Для гарантированной пропускной способности официальный API CoinMarketCap является лучшим вариантом.

Мои селекторы возвращают неверные значения. Что изменилось?

Почти наверняка разметка CoinMarketCap. Хешированные имена CSS-классов часто меняются, и порядок столбцов может смещаться, поэтому селекторы и позиционные индексы, работавшие в прошлом месяце, могут сломаться. Фиксируйтесь на стабильных хуках p.coin-item-name и p.coin-item-symbol там, где это возможно, заново проверяйте живую страницу в инструментах разработчика браузера при неверном поле и обновляйте селектор или индекс ячейки. Периодическое обслуживание селекторов нормально для любого рабочего парсера.

Стоит ли парсить CoinMarketCap или использовать его официальный API?

Для обучения, прототипирования и небольших задач с публичными данными парсинг публичной таблицы является хорошим способом получить название, символ, цену, рыночную капитализацию, изменение за 24 ч и объём. Для производственных систем, коммерческого использования или масштабных запросов используйте официальный API CoinMarketCap: он даёт вам поддерживаемый контракт, предсказуемые ограничения скорости и чёткие права использования. Выбирайте инструмент, соответствующий масштабу вашего проекта.

Какие крипто-данные можно законно собирать?

Ограничивайтесь публичными рыночными данными, отображаемыми без аккаунта: название монеты, символ, цена, рыночная капитализация, изменение за 24 ч и объём. Не собирайте данные аккаунтов, списков наблюдения или персональные данные, не трогайте ничего за логином и никогда не обходите аутентификацию. Соблюдайте условия использования и robots.txt CoinMarketCap, а для коммерческого или масштабного использования полагайтесь на официальный API, а не масштабируйте парсер против публичного сайта.

Начать создавать

Обходите любой сайт в масштабе, без борьбы с инфраструктурой.

Crawlbase берёт на себя прокси, отпечатки и CAPTCHA, чтобы ваша команда выпускала конвейеры данных вместо поддержки обвязки краулинга. 1 000 запросов бесплатно, без карты.

Самообслуживание · Звонок отдела продаж не требуется · Доступны корпоративные объёмы краулинга