Crunchbase является одним из крупнейших каталогов данных о компаниях и стартапах в интернете. Публичные профили компаний содержат структурированную информацию, которая лежит в основе рыночных исследований, анализа конкурентов, поиска потенциальных клиентов и исследований финансирования: название компании, чем она занимается, где находится, численность сотрудников, веб-сайт, рейтинг и основатели. Проблема в том, что Crunchbase рендерит эти профили на стороне клиента и активно противодействует автоматизированному трафику, поэтому обычный HTTP-запрос возвращает пустую оболочку вместо нужных данных.

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

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

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

  • Title название компании, например «OpenAI».
  • Description краткое описание деятельности компании.
  • Location местонахождение компании, например «San Francisco, California».
  • Employees диапазон численности персонала, например «1001-5000».
  • Company URL ссылка на собственный сайт компании.
  • Rank позиция компании в рейтинге Crunchbase.
  • Founded год основания компании.
  • Founders основатели компании.

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

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

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

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

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

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

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

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

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

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

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

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

bash
python --version

python -m venv crunchbase_env
source crunchbase_env/bin/activate

pip install crawlbase beautifulsoup4

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

Шаг 1: получение отрендеренного профиля

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

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("utf-8")
    print(f"Request failed: {response['status_code']}")
    return None

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

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

Crawlbase Crawling API

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

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

Имея отрендеренный HTML, загрузите его в BeautifulSoup и извлеките каждое поле по его селектору. Профили Crunchbase располагают основные данные в предсказуемой структуре, поэтому можно сопоставить название, описание, местоположение, численность сотрудников, веб-сайт, рейтинг, год основания и основателей с отдельными селекторами. Оберните всё извлечение в блок try/except, чтобы одно отсутствующее поле не прерывало весь прогон.

python
from bs4 import BeautifulSoup

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

def scrape_company(html):
    soup = BeautifulSoup(html, "html.parser")
    rows = ".section-content-wrapper li.ng-star-inserted"

    company_link = soup.select_one(f"{rows}:nth-of-type(5) a[role='link']")

    return {
        "title": text_of(soup, "h1.profile-name"),
        "description": text_of(soup, "span.description"),
        "location": text_of(soup, f"{rows}:nth-of-type(1)"),
        "employees": text_of(soup, f"{rows}:nth-of-type(2)"),
        "company_url": company_link["href"] if company_link else None,
        "rank": text_of(soup, f"{rows}:nth-of-type(6) span"),
        "founded": text_of(soup, ".text_and_value li:nth-of-type(4) field-formatter"),
        "founders": text_of(soup, ".text_and_value li:nth-of-type(5) field-formatter"),
    }

Вспомогательная функция text_of делает сразу два полезных дела: она запрашивает один элемент и возвращает None, если элемент отсутствует, вместо того чтобы выбрасывать исключение при вызове .get_text() на несуществующем объекте. Это делает извлечение устойчивым, когда одно поле отсутствует в конкретном профиле, что часто происходит, поскольку не каждая компания указывает рейтинг или веб-сайт. URL компании читается из атрибута href якоря, а не из его текста, поэтому обрабатывается отдельно.

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

Имена классов Crunchbase (маркеры Angular ng-star-inserted, элементы field-formatter и обёртки разделов) меняются без предупреждения. Рассматривайте приведённые выше селекторы как начальный шаблон, а не как контракт. Когда поле возвращается как None, заново проверьте живой профиль в инструментах разработчика браузера и обновите селектор. Периодическое обслуживание селекторов нормально для любого рабочего парсера, это не признак поломки.

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

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

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("utf-8")
    print(f"Request failed: {response['status_code']}")
    return None

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

def scrape_company(html):
    soup = BeautifulSoup(html, "html.parser")
    rows = ".section-content-wrapper li.ng-star-inserted"
    company_link = soup.select_one(f"{rows}:nth-of-type(5) a[role='link']")

    return {
        "title": text_of(soup, "h1.profile-name"),
        "description": text_of(soup, "span.description"),
        "location": text_of(soup, f"{rows}:nth-of-type(1)"),
        "employees": text_of(soup, f"{rows}:nth-of-type(2)"),
        "company_url": company_link["href"] if company_link else None,
        "rank": text_of(soup, f"{rows}:nth-of-type(6) span"),
        "founded": text_of(soup, ".text_and_value li:nth-of-type(4) field-formatter"),
        "founders": text_of(soup, ".text_and_value li:nth-of-type(5) field-formatter"),
    }

def main():
    page_url = "https://www.crunchbase.com/organization/openai"
    html = crawl(page_url)
    if not html:
        return
    data = scrape_company(html)
    print(json.dumps(data, indent=2))

if __name__ == "__main__":
    main()

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

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

json
{
  "title": "OpenAI",
  "description": "OpenAI is an AI research and deployment company.",
  "location": "San Francisco, California, United States",
  "employees": "1001-5000",
  "company_url": "https://openai.com",
  "rank": "5",
  "founded": "2015",
  "founders": "Elon Musk, Greg Brockman, Ilya Sutskever, Sam Altman"
}

Масштабирование на множество компаний

Один профиль подходит для демонстрации; реальная задача предполагает обработку списка компаний. Структура остаётся той же: держите список URL организаций, получайте каждый через Crawling API, парсите с помощью той же функции и собирайте строки. Поскольку каждый профиль имеет одинаковую структуру, уже написанный парсер работает для всех них без изменений.

python
companies = [
    "https://www.crunchbase.com/organization/openai",
    "https://www.crunchbase.com/organization/anthropic",
]

results = []
for url in companies:
    html = crawl(url)
    if html:
        results.append(scrape_company(html))

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

Чтобы найти URL компаний в масштабе, можно парсить публичные страницы поиска и каталога Crunchbase с тем же паттерном «получить, затем парсить», собирая ссылки на организации, а затем посещая каждую. Просто сохраняйте разумный объём и соблюдайте ограничения скорости, описанные ниже.

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

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

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

Для более широкой стратегии смотрите как парсить сайты без блокировок и более глубокое погружение в тему как обходить CAPTCHA при веб-скрейпинге. Если вы предпочитаете маршрутизировать собственный трафик через ротирующийся пул, а не использовать управляемый API, Smart AI Proxy (также называемый AI Proxy) предоставляет ту же ротацию резидентных IP в качестве подключаемого прокси-эндпоинта.

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

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

Несколько принципов, которых стоит придерживаться. Собирайте только публичные данные: название компании, описание, местоположение, диапазон численности персонала, веб-сайт, рейтинг, год основания и основателей, которых любой может видеть без аккаунта. Уважайте заявленные ожидания Crunchbase по скорости запросов и поддерживайте объём запросов достаточно низким, чтобы не создавать нагрузку на серверы. Избегайте персональных данных, включая любую информацию, связанную с идентифицируемыми лицами, помимо того, что публично указано в профиле компании. Если вы планируете коммерческое повторное использование данных, получите разрешение или официальное соглашение, а не считайте молчание согласием.

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

Итоги

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

  • Crunchbase рендерится на стороне клиента. Обычный запрос возвращает пустую оболочку, поэтому необходимо рендерить страницу до парсинга.
  • Рендеринг и доверенный IP нужны вместе. Crawling API с JS-токеном делает оба за один вызов; ajax_wait и page_wait управляют временем ожидания контента.
  • BeautifulSoup выполняет извлечение. Сопоставьте название, описание, местоположение, сотрудников, веб-сайт, рейтинг, год основания и основателей с текущими селекторами и ожидайте дрейфа этих селекторов.
  • Масштабирование путём цикла по URL. Один и тот же парсер работает для каждого профиля, поэтому реальная задача является лишь списком ссылок на организации с разумным темпом.
  • Оставайтесь в рамках публичных данных. Соблюдайте ToS и robots.txt Crunchbase, предпочитайте официальный Crunchbase API для лицензированных или массовых данных и никогда не трогайте аккаунты, данные Pro или персональную информацию.

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

Почему обычный запрос не возвращает данные с Crunchbase?

Потому что Crunchbase рендерит содержимое профилей на стороне клиента с помощью JavaScript. Начальный HTML является оболочкой, которая заполняется только после выполнения скриптов страницы в браузере, поэтому обычный HTTP-запрос возвращает статус 200 с пустыми полями компании. Чтобы получить реальные данные, необходимо сначала отрендерить страницу, что и делает JS-токен Crawling API.

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

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

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

Почти наверняка разметка Crunchbase. Маркеры Angular ng-star-inserted, элементы field-formatter и обёртки разделов изменяются без предупреждения, поэтому селекторы, работавшие в прошлом месяце, могут сломаться. Заново проверьте живой профиль в инструментах разработчика браузера и обновите селекторы. Периодическое обслуживание селекторов нормально для любого рабочего парсера.

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

Если вам нужны лицензированные данные, большой объём, гарантированная структура или права на коммерческое повторное использование, используйте официальный Crunchbase API. Он создан для этого и позволяет оставаться в рамках их условий. Парсинг публичных профилей с подходом из этого руководства подходит для небольших исследований публичных данных, когда доступа к API нет, при условии соблюдения ToS, robots.txt и ограничений скорости.

Могу ли я парсить финансовые данные или данные Pro с Crunchbase?

Нет, и это руководство их не охватывает. Финансовые данные и данные Crunchbase Pro находятся за логином или платным уровнем, поэтому они не являются публичными данными. Парсинг контента за логином или платным доступом, или обход аутентификации для его получения, выходит за рамки данной темы и нарушает условия Crunchbase. Для этих данных правильным путём является официальный Crunchbase API или лицензионное соглашение.

Как избежать блокировки при парсинге Crunchbase?

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

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

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

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

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