cURL, это самый быстрый способ получить веб-страницу из терминала. Он поддерживает HTTP, HTTPS, FTP и многое другое, поставляется практически на каждой машине, с которой вам придётся работать, и отлично делает ровно одно: отправляет запрос и возвращает необработанный ответ. Это делает cURL для веб-скрапинга естественным первым инструментом: будь то ручное зондирование эндпоинта, прототипирование запроса перед написанием настоящего кода или вставка однострочника в шелл-скрипт.

Это практическое руководство по работе с командной строкой. Вы научитесь получать страницы, сохранять их на диск, следовать редиректам, задавать заголовки и User-Agent, отправлять куки, POST-запросы с данными формы и JSON, маршрутизировать через прокси и читать HTTP-статус-коды. Затем мы рассмотрим, где голый cURL упирается в стену (JavaScript-рендеринг и антибот-блокировки), и как получить готовый HTML через Crawlbase Crawling API и Smart AI Proxy, не выходя из терминала.

Зачем вообще использовать cURL для скрапинга

Большинство скрапинговых задач в итоге решается на Python или Node, так зачем начинать с командной строки? Потому что cURL, это кратчайший путь от «интересно, что вернёт этот URL» к ответу. Ничего не нужно устанавливать, никаких скриптов писать, никаких зависимостей управлять. Вы вводите одну команду и видите точные байты, которые отправил сервер, включая заголовки. Когда скрапер ведёт себя неожиданно, воспроизвести запрос через cURL, быстрейший способ выяснить, проблема в вашем коде или на стороне сервера.

cURL также хорошо компонуется. Поскольку он пишет необработанный вывод в stdout, его можно сразу перенаправить в парсер, grep или файл, а затем обернуть в цикл по списку URL в несколько строк bash. Для небольших задач этого паттерна часто достаточно. Для крупных cURL остаётся инструментом, к которому обращаются для отладки запроса перед масштабированием.

Получить страницу через GET-запрос

Простейший скрапинг, это голый GET. Укажите cURL URL, и он выведет тело ответа в терминал.

bash
curl https://example.com

По умолчанию cURL выполняет GET-запрос, поэтому флаги добавлять не нужно. HTML заполняет терминал, это нормально для быстрого просмотра, но не для чего-то большего. Следующие несколько приёмов посвящены управлению этим выводом: как сохранить его, убрать лишнее и прочитать метаданные вокруг тела. Подробнее о стороне запроса смотрите в материале как отправлять GET-запросы с cURL.

Сохранить ответ в файл

Для сохранения есть два флага. Используйте -o, чтобы записать в файл с именем по вашему выбору, или -O (заглавная O), чтобы сохранить удалённое имя файла из URL.

bash
# Write the body to a named file
curl -o page.html https://example.com

# Keep the remote filename (saves as report.pdf)
curl -O https://example.com/files/report.pdf

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

Следовать редиректам с помощью -L

По умолчанию cURL не следует редиректам. Если URL возвращает 301 или 302, вы получаете сам ответ редиректа, а не страницу, на которую он указывает, это классическая причина, по которой скрапинг возвращает пустой результат. Флаг -L указывает cURL следовать заголовку Location до конечного назначения.

bash
curl -L https://example.com/old-path

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

Задать User-Agent и другие заголовки

cURL представляется User-Agent вида curl/8.4.0, и многие сайты мгновенно распознают это как не-браузерный клиент. Отправка реалистичного User-Agent, это единственный наиболее ценный заголовок, который можно задать. Используйте -H для добавления любого заголовка или специальный флаг -A для User-Agent.

bash
# Set a browser-like User-Agent with -A
curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" https://example.com

# Add multiple headers with repeated -H flags
curl https://example.com \
  -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)" \
  -H "Accept-Language: en-US,en;q=0.9" \
  -H "Referer: https://www.google.com/"

Реалистичные заголовки делают ваш запрос похожим на браузерный, а не на скриптовый. Разумный набор по умолчанию, актуальный User-Agent, пара Accept и Accept-Language, а иногда и Referer. Полную картину того, какие заголовки важны и почему, смотрите в материале как отправлять HTTP-заголовки с cURL.

Отправка и хранение куки

Некоторые страницы требуют сессию перед отдачей контента: куки согласия, выбор региона или состояние авторизации. cURL управляет куками с помощью двух флагов. Используйте -b для отправки куков и -c для сохранения куков, которые устанавливает сервер, в файл (хранилище куков), чтобы последующие запросы могли их повторно использовать.

bash
# Send a cookie inline
curl -b "consent=1; region=us" https://example.com

# First request: save cookies the server sets into a jar
curl -c cookies.txt https://example.com/start

# Second request: replay the saved cookies
curl -b cookies.txt https://example.com/dashboard

Паттерн «сохранить, затем воспроизвести» позволяет выполнить двухэтапный поток из командной строки: обратиться к стартовой странице для сбора куков, а затем использовать их при обращении к нужной странице. Можно объединить -b и -c в одном запросе, чтобы одновременно загружать и обновлять хранилище по мере развития сессии.

POST-запросы с данными формы и JSON

Скрапинг, это не всегда GET. Формы поиска, фильтры и API часто ожидают POST. Флаг -d отправляет данные и неявно переключает метод на POST. По умолчанию он отправляет данные в form-encoded формате; установите Content-Type: application/json, чтобы отправить JSON-тело.

bash
# Form-encoded POST (application/x-www-form-urlencoded)
curl -d "query=laptops&page=2" https://example.com/search

# JSON POST: set the method and content type explicitly
curl -X POST https://example.com/api/search \
  -H "Content-Type: application/json" \
  -d '{"query": "laptops", "page": 2}'

Для данных формы разделяйте поля символом &, как это делает браузер. Для JSON оберните тело в одинарные кавычки, чтобы оболочка не трогала двойные, и всегда отправляйте соответствующий Content-Type, иначе сервер может отклонить или неверно интерпретировать полезную нагрузку. Прямое обращение к JSON API таким способом зачастую чище, чем скрапинг отрисованного HTML, когда эндпоинт доступен.

Маршрутизация cURL через прокси

Скрапинг с одного IP-адреса в большом объёме приводит к ограничению скорости или блокировке этого IP. Маршрутизация через прокси подставляет другой адрес перед вашим запросом. Флаг -x задаёт прокси, с необязательными учётными данными user:pass@.

bash
# Plain HTTP proxy
curl -x http://proxy.example.com:8080 https://example.com

# Authenticated proxy
curl -x http://user:[email protected]:8080 https://example.com

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

Тихий режим, подробный вывод и чтение статус-кода

При написании скриптов вам обычно нужно, чтобы cURL молчал, но когда что-то ломается, нужно всё. Флаг -s отключает индикатор прогресса; -v выводит полный обмен запросом и ответом, включая все заголовки, что неоценимо при отладке блокировки. Чтобы прочитать только HTTP-статус-код, используйте шаблон write-out.

bash
# Silent: no progress meter, just the body
curl -s https://example.com -o page.html

# Verbose: see the full request/response exchange
curl -v https://example.com

# Print only the HTTP status code, discard the body
curl -s -o /dev/null -w "%{http_code}\n" https://example.com

Последняя команда, настоящая рабочая лошадка: она отбрасывает тело, выводит только статус-код и даёт скрипту чистый сигнал для ветвления. 200 означает продолжать; 403 или 429 означает, что вас проверяют или ограничивают скорость, и нужно отступить или сменить тактику. Чтение статус-кодов, это то, как отличить нормальный прогон от заблокированного.

Передать вывод cURL в парсер

cURL получает данные, но не парсит их. Unix-ответ, это перенаправить вывод в инструмент, который умеет это делать. Для быстрого извлечения поля используйте grep или небольшой однострочник на Python; для реальных HTML-запросов трудно превзойти инструмент вроде htmlq (CSS-селекторы в командной строке).

bash
# Grab the <title> with grep
curl -s https://example.com | grep -o '<title>[^<]*</title>'

# Parse properly with htmlq (CSS selectors)
curl -s https://example.com | htmlq 'h1' --text

# Hand the HTML to Python for structured extraction
curl -s https://example.com | python3 -c \
  "import sys; from bs4 import BeautifulSoup; \
print(BeautifulSoup(sys.stdin.read(), 'html.parser').title.text)"

Регулярные выражения с grep подходят для разового извлечения поля, но ненадёжны на реальной разметке; как только структура становится вложенной, переходите к HTML-парсеру. Python-пайп естественно масштабируется в полноценный скрипт BeautifulSoup, когда извлечение вырастает за пределы одного селектора.

Цикл по списку URL в bash

Один URL, это тест; скрапинг, это список. Короткий bash-цикл читает URL из файла, получает каждый, проверяет статус и сохраняет успешные. Паузы между запросами не дают перегружать сервер.

bash
while read url; do
  slug=$(echo "$url" | md5sum | cut -c1-8)
  code=$(curl -s -L -o "out_$slug.html" -w "%{http_code}" "$url")
  echo "$code  $url"
  sleep 2
done < urls.txt

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

Где голый cURL упирается в стену

cURL, это HTTP-клиент, а не браузер. Это различие и объясняет, где он перестаёт работать для современного скрапинга, и проявляется это двумя способами.

Он не может выполнять JavaScript. cURL получает только тот сырой HTML, который отправляет сервер, и ничего более. На сайте с клиентским рендерингом (большинство React, Vue и Angular приложений) этот начальный HTML, почти пустая оболочка; реальный контент отрисовывается скриптами, выполняющимися в браузере. cURL их никогда не запускает, поэтому вы получаете скелет без данных. Никакой флаг это не исправит, потому что JavaScript-движка просто нет.

Его блокируют. Даже на страницах с серверным рендерингом антибот-системы анализируют запрос: IP дата-центра, отсутствующий или стандартный User-Agent, браузероподобный набор заголовков отсутствует, и TLS-отпечаток не соответствует реальному браузеру. Голый cURL проваливает большинство этих проверок и получает 403, CAPTCHA или тихую страницу-приманку. Частично это можно скрыть с помощью заголовков и прокси, но на сложных целях это проигрышная гонка вооружений. Более широкий план действий изложен в материале как скрапить сайты, не попадая в блокировку.

The two-part problem

Работающий скрапинг современного сайта требует двух вещей одновременно: браузера, который реально отрисовывает страницу, и IP-адреса, который сайт воспринимает как настоящего посетителя. cURL не даёт ни того, ни другого. Можно самостоятельно собрать headless-браузер плюс пул ротирующихся резидентских прокси, но поддержание этого стека в рабочем состоянии и составляет основную часть работы. В следующем разделе оба компонента сворачиваются в один вызов cURL.

Получить готовый HTML с помощью Crawling API

Самый чистый способ продолжать использовать cURL, решая проблемы рендеринга и блокировки, обращаться к Crawlbase Crawling API из командной строки. Вы передаёте свой токен и целевой URL; API получает страницу через доверенный резидентский IP и возвращает HTML. Добавьте &javascript=true, и страница будет отрисована в реальном браузере, так что контент на стороне клиента окажется в том, что вы получите обратно.

bash
# Static fetch through the Crawling API
curl "https://api.crawlbase.com/?token=YOUR_TOKEN&url=https://example.com"

# JavaScript-rendered fetch for client-side pages
curl "https://api.crawlbase.com/?token=YOUR_JS_TOKEN&javascript=true&url=https://example.com"

URL для скрапинга передаётся в параметре url и должен быть URL-кодирован, если содержит собственную строку запроса. Используйте обычный токен для статических страниц и JavaScript-токен с javascript=true для страниц с рендерингом. Поскольку ответ, это просто HTML в stdout, все приёмы с пайпами и парсингом из предыдущих разделов по-прежнему применимы: перенаправьте в файл, передайте в htmlq или отдайте Python-парсеру. Вы сохраняете рабочий процесс cURL и перекладываете проблемы рендеринга и IP на чужие плечи.

Crawlbase Crawling API

Голый cURL блокируется и не может выполнять JavaScript. Crawling API принимает ваш токен и URL, получает страницу через ротирующийся резидентский IP, при необходимости отрисовывает её в реальном браузере и возвращает готовый HTML в stdout, так что он сразу встраивается в ваши существующие пайпы и циклы cURL. Начните на бесплатном тарифе и сохраните привычный командный рабочий процесс.

Маршрутизация cURL через Smart AI Proxy

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

bash
curl -x http://YOUR_TOKEN:@smartproxy.crawlbase.com:8012 -k \
  https://example.com

Здесь ваш токен служит именем пользователя прокси (пароль оставляется пустым), и каждый запрос через этот эндпоинт автоматически ротируется по резидентскому пулу. Флаг -k указывает cURL принимать TLS-перехват прокси. Это правильный выбор, когда ваш скрапер уже построен вокруг cURL или поддержки прокси в библиотеке и вам нужна только ротация IP, а не полный серверный рендеринг. Для страниц с клиентским рендерингом предпочтительнее Crawling API с javascript=true.

Итоги

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

  • cURL, самый быстрый инструмент для получения данных и отладки. Простой curl URL выводит ответ; -o/-O сохраняет его, -L следует редиректам, а -s/-v управляют шумом.
  • Заголовки и куки делают вас похожим на браузер. Задайте реальный User-Agent с помощью -A или -H, а -b/-c используйте для отправки и хранения куков в рамках сессии.
  • POST и прокси закрывают остальные основные задачи. -d отправляет данные формы или JSON (с правильным Content-Type), а -x маршрутизирует через прокси.
  • Пайпы и циклы для масштабирования. Перенаправляйте вывод cURL в grep, htmlq или Python, и оборачивайте в bash-цикл с проверкой статусов и паузами для работы со списком URL.
  • Голый cURL не рендерит JS и попадает в блокировку. Вызывайте Crawling API (добавьте javascript=true для рендеринга) или маршрутизируйте через Smart AI Proxy, чтобы получать готовый HTML в рамках рабочего процесса cURL.

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

Можно ли использовать cURL для веб-скрапинга?

Да. cURL выполняет HTTP-запросы и возвращает необработанный ответ, который можно сохранить в файл или передать в парсер, например grep, htmlq или Python-скрипт. Он отлично подходит для статических, серверно-рендеренных страниц и для отладки запросов. Его ограничения: он не может выполнять JavaScript и легко блокируется антибот-системами, поэтому для страниц с клиентским рендерингом или защищённых сайтов его сочетают с сервисом рендеринга и прокси.

Почему cURL возвращает пустую или частичную страницу?

Обычно это одна из двух причин. Либо сайт рендерится на стороне клиента, и реальный контент отрисовывается JavaScript, который cURL никогда не запускает, и вы получаете только HTML-оболочку. Либо сайт обнаружил небраузерный запрос и вернул страницу блокировки или приманки. Проверьте статус-код с помощью -w "%{http_code}": 200 без данных указывает на JavaScript-рендеринг, тогда как 403 или 429, на блокировку.

Как задать User-Agent в cURL?

Используйте флаг -A с браузероподобной строкой, например curl -A "Mozilla/5.0 (...)" https://example.com, или задайте его как заголовок через -H "User-Agent: ...". Идентификатор по умолчанию curl/x.y.z мгновенно выдаёт, что запрос не браузерный, поэтому реалистичный User-Agent, первый заголовок, который следует исправить, когда страница вас блокирует.

Как отправить POST-данные с cURL?

Используйте -d, который отправляет данные и автоматически переключает метод на POST. По умолчанию он отправляет form-encoded данные (-d "a=1&b=2"). Для JSON добавьте -H "Content-Type: application/json" и передайте тело как строку в одинарных кавычках, чтобы оболочка не испортила двойные кавычки.

Как использовать прокси с cURL?

Используйте флаг -x: curl -x http://host:port https://example.com, добавив user:pass@ перед хостом для аутентифицированного прокси. Однако единственный статический прокси меняет ваш IP только один раз; для скрапинга в большом объёме нужна ротация по множеству IP-адресов, которую такой сервис, как Smart AI Proxy, предоставляет через один эндпоинт.

Как скрапить страницы с большим количеством JavaScript с помощью cURL?

С одним только cURL это невозможно, поскольку у него нет JavaScript-движка и он никогда не выполняет скрипты, которые отрисовывают контент. Практическое решение, вызвать сервис рендеринга из cURL: отправьте URL в Crawling API с javascript=true, и он отрисует страницу в реальном браузере, затем вернёт готовый HTML в stdout, где ваши привычные пайпы и парсинг по-прежнему работают.

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

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

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

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