Curl запрос как из браузера
Предварительные сведения
Используя ключ -v , можно увидеть, какие именно команды curl отсылает серверу. Этот ключ дает возможность разобраться в особенностях взаимодействия curl и веб-сервера и помогает отладить запрос.
Формы
Справка
Справку по curl можно получить, набрав в командной строке
$ — приглашение командной строки.
Получить содержимое страницы (GET)
вы получите веб-страницу, выведенную в окно терминала (точнее, в стандартный вывод). Чтобы сохранить эту страницу в файл curl.html , нужно указать
Форма запроса может использовать метод GET. Например, так:
Для формирования GET-запроса, введите то, что ожидалось от формы:
Метод POST
Форма, генерирующая POST-запрос, отличается от предыдущей лишь методом отправки:
curl сформирует POST-запрос с теми же данными следующим образом:
Обратите внимание на то, что данные, которые вы отправляете серверу, должны быть правильно закодированы. curl не сделает этого за вас. К примеру, если вы хотите, чтобы данные содержали пробел, то вам нужно заменить этот пробел на %20 и т. п. Это одна из самых распространенных ошибок, в результате чего данные передаются не так, как нужно.
Загрузка файлов с помощью POST
Форма, с помощью которой пользователь может загрузить файл, выглядит примерно так:
Заметьте, что тип содержимого Content-Type установлен в multipart/form-data .
Чтобы с помощью curl отослать данные в такую форму, введите:
Скрытые поля формы
Скрытые поля в формах являются одним из наиболее распространенных способов передачи информации о состоянии HTML-приложения. Такие поля не заполняются, они невидимы для пользователя, но передаются так же, как и обычные поля.
Пример формы с одним видимым и одним скрытым полями:
Как выглядит POST-запрос "изнутри"
Когда с помощью curl вы заполняете форму и отсылаете ее данные на сервер, вы наверняка хотите, чтобы сформированный curl POST-запрос выглядел так же, как если бы он был выполнен с помощью браузера.
Простейший способ увидеть свой POST-запрос заключается в следующем:
Вы увидите, что данные присоединились к URL и разделены символами ? , как это и предполагается при использовании GET-форм.
Комментарии
Дмитрий Храмов
Компьютерное моделирование и все, что с ним связано: сбор данных, их анализ, разработка математических моделей, софт для моделирования, визуализации и оформления публикаций. Ну и за жизнь немного.
GET запрос при помощи cURL
cURL - мощный инструмент для отправки запросов. Только взгляните сколько он всего умеет.
Все настройки, которые вы можете найти по этой ссылке. Там вы найдете опции, которые мы будем устанавливать функцией curl_setopt, в дальнейших примерах.
Пример простого GET запроса при помощи cURL:
В итоге, переменная $result снова содержит html код страницы этого сайта.
- CURLOPT_VERBOSE - установлена в true для вывода дополнительной информации. Записывает вывод в поток STDERR, или файл, указанный параметром CURLOPT_STDERR.
- CURLOPT_RETURNTRANSFER - установлена в true, для того чтобы вернуть ответ сервера. Если вам ответ сервера не нужен, то можете убрать эту опцию.
Если в результате сервер вернет нам редирект, то мы по нему автоматически не перейдем. А иногда это бывает полезно. Чтобы cURL автоматически шел по редиректу нужно установить опцию CURLOPT_FOLLOWLOCATION.
С установленной опцией скрипт автоматически перейдет по вернувшемуся редиректу и вернет ответ уже с итоговой страницы.
POST запрос при помощи cURL
Отлично, с GET и POST запросами в cURL мы немного освоились. Теперь разберемся с заголовками, которые мы можем отсылать в запросе.
cURL: POST запрос в формате JSON
Отличия конфигурации JSON запроса от обычного POST запроса заключается в том, что мы кодируем поля при помощи json_encode() И добавляем заголовок Content-Type: application/json
cURL: GET запрос в формате JSON
GET запрос в формате JSON отправляется так же как и POST запрос, просто нужно CURLOPT_CUSTOMREQUEST установить в 'GET'
А в остальном код идентичен предыдущему примеру. Хотя, надо признать, GET запросы с телом - это нонсенс. Обычно для этих целей используется POST, PUT или PATCH, но был у меня один случай. Поэтому вот GET запрос в формате JSON.
Стоп, Дмитрий, прекрати выдумывать виды запросов!
Это делается по тому же принципу, как и CURLOPT_POST. Но что делать с остальным зоопарком запросов? Разве у cURL есть CURLOPT_DELETE или CURLOPT_HEAD? Нет.
Для того, чтобы отправлять другие виды запросов есть другая опция: CURLOPT_CUSTOMREQUEST
Вместо строки curl_setopt($curl, CURLOPT_POST, true); мы явно задаем имя запроса опцией CURLOPT_CUSTOMREQUEST:
Замечание: Не используйте эту возможность пока не убедитесь, что сервер поддерживает данный тип запроса.
Как получить заголовки ответа
В предыдущем примере мы научились посылать заголовки. Самый правильный способ принять заголовки:
Иногда можно встретить другой вариант получения заголовков ответа. К сожалению, они не совсем правильные и могут работать некорректно в некоторых случаях.
Рассмотрим такой пример:
Мы сначала определяем размер заголовка, с помощью CURLINFO_HEADER_SIZE затем вырезаем его из ответа. К сожалению, это может не срабатывать, когда используется прокси или в некоторых случаях редиректа.
Скачивание больших файлов с помощью cURL
Для того, чтобы скачать большой файл пригодится этот способ:
Обратите внимание, если вы будете использовать file_get_contents для скачивания файлов, то файл сначала загружается в оперативную память, а потом сохраняется на диск. Поэтому если файл действительно большой, то скорее всего вашему серверу не хватит памяти. Также к памяти будет требователен следующий код:
Здесь мы скачиваем файл при помощи cURL в оперативную память, а затем сохраняем его на диск. Не смотря на то, что этот способ не годится для скачивания больших файлов, с помощью него можно вполне сохранить простую веб страницу.
Параллельные cURL запросы в PHP
Для чего могут потребоваться многопоточные запросы? Например у нас есть много URL адресов:
И если мы будем по очереди отправлять запросы, то второй запрос начнется только после того, как закончился первый и так далее, а это существенно увеличивает время работы скрипта.
Выглядит это так:
Теперь в $results у нас содержится массив, где ключи - это url адреса, а значения - результаты запросов. Однако запросы выполняются долго. Но мы можем это ускорить.
Как выполнить 3 запроса одновременно? В этом нам поможет curl_multi_
Такие параллельные запросы выполняются значительно быстрее чем поочередные.
cURL запросы с сохранением и загрузкой cookie из файла
cURL позволяет нам установить cookie при передачи запросов, а также автоматически принимать и устанавливать cookie, которые нам возвращает сервер, сохраняя их между запросами.
Давайте рассмотрим такой пример:
Теперь cookie у нас хранятся в файле cookie.txt в директории со скриптом (если вы ничего не меняли). Если мы совершаем повторные запросы, то cURL автоматически берет и отправляет cookie на сервер, как и обычный браузер. Таким образом мы можем авторизироваться на сайте и сохранить сеанс между запросами.
Передача cookie без файлов
Иммитация браузера с помощью cURL
Иногда сайт, к которому мы обращаемся может фильтровать запросы, защищаясь от парсинга. Если для этого используются упрощенные способы защиты, например проверка User-Agent, то мы можем легко притвориться, что являемся реальным польователем, который взаимодействует с сайтом через браузер, мы можем послать заголовки и cookie, которые обычно посылает браузер.
В данном примере установлены заголовки, которые посылает Chrome.
В простых ситуациях этого хватает. Но если используется защита при помощи javascript или что-то более продвинутое, то здесь cURL бессилен, и следует использовать либо BAS либо Zennoposter. Либо если вы хотите попытать счастье с PHP, то Selenium.
Не используйте эти знания в противоправных целях.
cURL запросы через прокси
Простой пример для отправки запросов через proxy. Если ваш прокси предполагает авторизацию, то раскомментируйте соответствующие строчки.
Отправка файлов
Авторизация с помощью cURL
OAuth авторизация
Авторизация через форму
Допустим на сайте есть такая форма:
Тогда наш cURL запрос должен быть сформирован так:
Автоматическое построение запросов
Перевод консольной команды curl в PHP
Так вы можете создать простые запросы на cURL в PHP не создавая их вручную.
Лайфхак
В консоли браузера, во вкладке сеть, вы можете кликнуть правой кнопкой мыши и скопировать любой запрос в виде команды cURL, а потом с помощью сервиса curl-to-php перевести запрос в PHP. Теперь вы вообще можете сконвертировать в cURL абсолютно любой запрос, который посылает ваш браузер.
Как работать с cURL гораздо проще
Вы можете спросить: почему у cURL такие кривые и страшные методы? У вас может возникнуть желание взять и создать обертку для работы с cURL, чтобы вы могли не писать каждый раз большие куски некрасивого кода, а писать все проще, например так:
Просто установите ее при помощи: composer require php-curl-class/php-curl-class и не работайте с кривыми кусками кода, которые таковы вероятно потому, что cURL изначально консольное приложение.
POST и GET запросы без cURL
Теперь у нас в переменной $result записан весь html код главной страницы этого сайта. Мы совершили GET запрос, а html код - это ответ на него.
Как видите file_get_contents - полезная функция, которая не только позволяет читать файлы на нашем сервере, но еще и отправлять запросы.
В прошлой статье по написанию своего первого парсера я описал основы работы с cURL. Текущая статья будет одной из цикла статей по экскурсу в написание ботов и парсеров. Однако, эта статья, в основном, будет похожа на шпаргалку, в большей мере, чем на туториал.
PHP cURL основы
- curl_init ([ string $url = NULL ] ) - с него начинается инициализация сессии cURL
- curl_setopt ( resource $ch , int $option , mixed $value ) - конфигурирование настроек текущей сессии cURL
- curl_exec ( resource $ch ) - выполняем запрос, получаем результат
- curl_close ( resource $ch ) - закрытие сессии. В реальности, можно игнорировать выполнение curl_close(), так как PHP сделает это за нас, после выполнения скрипта
Отправка GET запроса из PHP cURL
Здесь всё просто, PHP cURL GET запрос - это самое простое, что можно придумать.
В результате выполнения этого кода, переменной $response будет присвоен ответ от сервера, к которому мы стучались (в основном - это HTML или JSON).
Иногда стоит необходимость отправки GET-запроса, формируя URL-адрес из Query-параметров. Для таких случаев, можете воспользоваться встроенной PHP-функцией, формирующей URL-строку с параметрами из массива:
Теперь вы знаете, как склеить массив данных в URL из PHP.
Отправка POST запроса из PHP cURL
PHP cURL POST запрос обычно не выполняется с пустым телом. Запрос этого типа считается запросом на добавление данных (создание новой сущности в БД, к примеру) и обычно нам необходимо передавать серверу набор каких-то данных. Код отправки POST-запроса с передачей данных будет выглядеть так:
Отправка cURL запроса из PHP с собственными заголовками (PHP cURL Headers)
Отправка POST JSON запроса в PHP cURL
Очень часто, при написании ботов, имитирующих взаимодействие с API, приходится отправлять данные на целевой сервер в формате JSON. И так сложилось, что отправка Form-Data POST параметров отличается от алгоритма отправки JSON данных, потому, и передавать эти данные для cURL нужно по-другому.
Если вы хотите протестировать корректность отправки данных в "принимающем" PHP-скрипте, то данные нужно считывать не с массива $_POST, а с тела запроса. И для этого, нужно выполнить код:
Основной принцип передачи данных в JSON с помощью CURL заключается в том, что нужно выполнить POST запрос, тело которого заполнить закодированными в JSON данными, после чего, указать соответствующий заголовок позволяющий серверу понять, что ему на обработку пришли JSON данные.
Резюме
Забегу наперёд, и скажу, что для написания бота для этого сайта, необходимо будет эмулировать AJAX запросы из PHP, и обрабатывать JSON ответ от сервера.
Перед тем, как приступить к изучению этой статьи, советую сначала разобраться с основами PHP cURL, и основыми функциями по работе с ним. После чего, продолжите изучение этой.
Шаг 1 - изучаем жертву
Для того, чтобы понять, какие параметры нужно отправлять, и на какой URL-адрес, нужно:
- включить отладочную панель в браузере (f12)
- открыть вкладку Network (она же Сеть )
- включить опцию Preserve log (если не включить её, то вся история запросов будет очищена при перезагрузку страницы, оно вам надо?).
После чего, нам нужно провести цикл действий, которые мы собираемся автоматизировать (наблюдая при этом за каждым выполненным запросом и переданными данными). Наш цикл действий состоит только из заполнения почты и клика по кнопке Зарегистрироваться .
И после клика по кнопке регистрации, будет отправлен AJAX-запрос, который мы увидим в открытой панеле. И уже из информации на этой панеле, мы можем изучить все данные, которые нам необходимо будет сэмулировать PHP-скриптом.
В нашем случае, на панеле добавится запрос на ajax_light_register , по которому мы должны кликнуть, для просмотра дополнительной информации. А именно, нас интересует URL-адрес, на который отправляются данные для регистрации, метод, данные, и их формат:
Однако, здесь есть один тонкий момент. Для того, чтобы полностью сэмулировать работу браузера, реального пользователя, нужно передать так же заголовки, которые помогут нам не выдать себя за бота.
Я выделил основные заголовки, которые в большей мере котируются сервером, которые желательно отправлять. Сейчас, кратко рассмотрим их назначение:
Теперь, когда мы изучили основные параметры для написания собственного бота, объединим всю полученную информацию, и напишем скрипт на PHP.
Шаг 2 - изучаем ответ, полученный от сервера
Для того, чтобы сходу не спаммить лишний раз запросами к серверу, у нас есть возможность изучить пример ответа, когда мы пройдём регистрацию из браузера. Для этого, в открытой панеле информации о запросе нужно перейти на вкладку Preview , которая отображает ответ, полученный от сервера.
И вот, что мы имеем при успешном запросе:
Посмотрев на него, можно увидеть, что данные приходят в формате JSON, и содержат поля: errors (с массивом ошибок, если они есть), и errors_exists - булев флаг, показывающий, были ли ошибки при выполнении скрипта.
И, теперь, можем приступить к последнему шагу - написанию скрипта на PHP.
Шаг 3 - пишем скрипт и тестируем
Получив всю нужную информацию, напишем скрипт, который будет отправлять данные, полученные в шаге 1, и обрабатывая ответ, исходя из изученного примера во втором шаге.
В результате чего, выполнив написанный скрипт, регистрация будет выполнена успешно, и на указанную почту будет отправлена ссылка для входа в личный кабинет.
Резюме
В этой статья я продемонстрировал подход, которому следую при написании ботов на PHP. В этой статье были затронуты темы написания ботов, эмулирующих AJAX-запросы на PHP, темы возможных защит и бот-детекторов, которые мы научились обходить. Итого, из
этой статьи на узнали, как написать бота на PHP, как в PHP определяют ботов, как в PHP cURL задать User-Agent, и зачем он нужен, и как при написании собственного бота не попасться на эти детекторы. Дальше - больше: продвинутые темы парсинга, полезные инструменты, написания ботов на PHP, многопоточная работа.
Читайте также: