Примеры использования cURL в PHP

Soft – урок по curl: основы использования и пара полезных трюков (часть первая)

Для чего нужна cURL

  • cURL отлично подходит для имитации действий пользователя в браузере.

Реальный практический пример: вам нужно перезагрузить роутер (модем) для смены IP адреса. Для этого нужно: авторизоваться в роутере, перейти к странице обслуживания и нажать кнопку «Перезагрузка». Если это действие нужно выполнить несколько раз, то процедуру нужно повторить. Согласитесь, делать каждый раз в ручную эту рутину не хочется. cURL позволяет автоматизировать всё это. Буквально несколькими командами cURL можно добиться авторизации и выполнения задания на роутере.

  • cURL удобен для получения данных с веб-сайтов в командной строке.

Ещё один практический пример: мы хотим реализовать показ общей статистики для нескольких сайтов. Если использовать cURL, то это становится вполне тривиальной задачей: с помощью cURL мы проходим аутентификацию на сервисе сбора статистики (если это требуется), затем (опять же командами cURL) получаем необходимые страницы, парсим нужные нам данные; процедура повторяется для всех наших сайтов, затем мы складываем и выводим конечный результат.

Т.е. случаи использования cURL вполне реальные, хотя, в большинстве, cURL нужна программистам, которые используют её для своих программ.

cURL поддерживает множество протоколов и способов авторизации, умеет передавать файлы, правильно работает с кукиз, поддерживает SSL сертификаты, прокси и очень многое другое.

cURL в PHP и командной строке

Мы можем использовать cURL двумя основными способами: в скриптах PHP и в командной строке.

Чтобы включить cURL в PHP на сервере, необходимо в файле php.ini раскомментировать строку

А затем перезагрузить сервер.

На Linux необходимо установить пакет curl.

На Debian, Ubuntu или Linux Mint:

На Fedora, CentOS или RHEL:

Чтобы наглядно было видно разницу в использовании в PHP и в командной строке, будем одни и те же задачи выполнять дважды: сначала в скрипте PHP, а затем в командной строке. Постараемся при этом не запутаться.

Получение данных при помощи cURL
Получение данных при помощи cURL в PHP

Пример на PHP:

Всё очень просто:

$target_url

— адрес сайта, который нас интересует. После адреса сайта можно поставить двоеточие и добавить адрес порта (если порт отличается от стандартного).

curl_init

— инициализирует новый сеанс и возвращает дискриптор, который в нашем примере присваивается переменной

$ch

.

Затем мы выполняем запрос cURL функцией

curl_exec

, которой в качестве параметра передаётся дискриптор.

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

Чуть дополним наш скрипт:

У нас появилась строчка

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

.

curl_setopt

— задаёт опции. Полный список опций можно найти на этой странице:

http://php.net/manual/ru/function.curl-setopt.php
$response_data = curl_exec($ch);

Теперь значение скрипта присваивается переменной $response_data, с которой можно проводить дальнейшие операции. Например, можно вывести её содержимое.

Строчки

служат для отладки, на случай возникновения ошибок.

Получение данных при помощи cURL в командной строке

В командной строке достаточно набрать

где вместо

mi-al.ru

— адрес вашего сайта.

Если нужно скопировать данные в переменную, а не выводить полученный результат на экран, то делаем так:

При этом всё равно выводятся некие данные:

Чтобы они не выводились, добавляем ключ

-s

:

Можно посмотреть, что записалось:

Базовая аутентификация и аутентификация HTTP

Аутентификация, проще говоря, это введение имени пользователя и пароля.

Базовая аутентификация — это аутентификация средствами сервера. Для этого создаются два файла:

.htaccess

и

.htpasswd

Содержимое файла .htaccess примерно такое

Содержимое файла .htpasswd примерно такое:

Т.е. логин и хэш пароля.

При попытке получить доступ к запароленной папке, в браузере отобразиться примерно такое окно:

HTTP аутентификация — это тот случай, когда мы вводим логин и пароль в форму на сайте. Именно такая аутентификация используется при входе в почту, на форумы и т. д.

Базовая аутентификация cURL (PHP)

Есть сайт

http://62.113.208.29/Update_FED_DAYS/

, который требует от нас авторизоваться:

Пробуем наш первоначальный скрипт:

Хотя скрипт и считает, что ошибки нет, но выводимый результат нам совсем не нравится:

Добавляем две строки:

Первой строкой мы задаём тип аутентификации — базовая. Вторая строка содержит имя и пароль через двоеточие (в нашем случае имя и пароль одинаковые — ru-board). Получилось так:

Я не забыл указать тип аутентификации, просто в cURL базовый тип аутентификации является дефолтным.

В командной строке всё получилось так быстро, что от расстройства я написал вот такую программу. Она подключается к сайту и скачивает самое последнее обновление:

Буквально ещё несколькими командами можно добавить:

  • распаковку архива в указанный каталог;
  • запуск обновлений КонсультантПлюс (это обновления для него);
  • можно реализовать проверку — было ли уже скачено последнее доступное обновление или появилось новое;
  • добавить это всё в Cron для ежедневных обновлений.

HTTP аутентификация cURL
HTTP аутентификация cURL в PHP

Нам нужно знать:

Иногда этих данных оказывается недостаточно. Давайте разберёмся.

Адрес, куда нужно отправить данные, можно взять из формы аутентификации. Например:

Мы смотрим на свойство

action

. Т.е. конечной страницей является

login.php

. Нам нужен полный адрес, например такой

http://188.35.8.64:8080/login.php

Здесь же мы находим и метод отправки:

method=”post”

Логин и пароль я тоже знаю: admin и qwerasdfzxcv

Т.е. на сервер из формы передаётся строка

LOGIN_USER=admin&LOGIN_PASSWD=qwerasdfzxcv

методом POST. Теоретически, наш предыдущий скрипт, в которое мы добавили новую строчку, должен работать. Т.е. должна происходить аутентификация.

В скрипте новая строка

curl_setopt($ch, CURLOPT_POSTFIELDS, ‘LOGIN_USER=admin&LOGIN_PASSWD=qwerasdfzxcv’);

Здесь

curl_setopt

— уже знакомая нам функция по установлению опций для cURL,

CURLOPT_POSTFIELDS

— эта имя опции, которую мы устанавливаем.

CURLOPT_POSTFIELDS

содержит все данные, которые передаются методом POST. Ну и сама строчка

LOGIN_USER=admin&LOGIN_PASSWD=qwerasdfzxcv

— это те самые данные, которые мы передаём.

Если внимательно изучить форму, то можно увидеть, что она содержит также и скрытые поля. А ещё данные могут обрабатываться или дополняться JavaScript’ами. Можно заняться изучением всего этого, но я предпочитаю более простой способ.

Я использую Wireshark. Эта программа предназначена для снифинга (перехвата) трафика. И именно в ней очень удобно смотреть, что же именно передаётся на сайт.

Посмотрите это крошечное видео:

Т.е. с адресом, куда передаются данные, я угадал. А вот передаваемая строка оказалась намного сложнее.

Я вписал верный параметр, а также чуть доработал скрипт, чтобы он не просто авторизовался, но и кое-что получал из роутера:

PHP:

<?php
        $target_url = "http://188.35.8.64:8080/login.php";
        $ch = curl_init($target_url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, 'ACTION_POST=LOGIN&FILECODE=&VERIFICATION_CODE=&LOGIN_USER=admin&LOGIN_PASSWD=qwerasdfzxcv&login=Log In &VER_CODE=');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $response_data = curl_exec($ch);
        if (curl_errno($ch) > 0) {
            echo 'Ошибка curl: ' . curl_error($ch);
        } else {
            $target_url2 = "http://188.35.8.64:8080/bsc_wlan.php";
            $ch2 = curl_init($target_url2);
            curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
            $response_data2 = curl_exec($ch2);
            preg_match('|f.ssid.value = "(.*)";|', $response_data2, $results2);
            $results2[0] = str_replace('f.ssid.value = "', '', $results2[0]);
            $results2[0] = str_replace('";', '', $results2[0]);
            echo "Имя wi-fi сети: <b>$results2[0]</b><br />";
            preg_match('|f_wpa.wpapsk1.value(.*)";|', $response_data2, $results3);
            $results3[0] = str_replace('f_wpa.wpapsk1.value', '', $results3[0]);
            $results3[0] = str_replace('="', '', $results3[0]);
            $results3[0] = str_replace('";', '', $results3[0]);
            echo "Пароль wi-fi сети: <b>$results3[0]</b>";
        }
        curl_close($ch);
        ?>

Кстати, если владелец обновит пароль (но не обновит прошивку), то новый пароль всегда можно посмотреть по адресу http://188.35.8.64:8080/model/__show_info.php?REQUIRE_FILE=/var/etc/httpasswd

(Это общеизвестная уязвимость роутеров D-Link DIR-300, D-Link DIR-320, и D-Link DAP-1353).

HTTP аутентификация cURL в командной строке

Полный адрес, а также строку, которую нужно передать, мы уже знаем. Поэтому всё просто:

Думаю, всё и так понятно, т. к. эти сроки мы уже рассмотрели. Если кому-то непонятно — спрашивайте в комментариях.

Примером использования cURL для получения и парсинга данных может стать следующий набор команд:

Сложные случаи авторизации: AJAX, JQuery, JavaScript и т.п.

Данные заголовок правильнее было бы написать так: «Сложные» случаи авторизации. Т.е. слово «сложные» взять в кавычки. Сложными они видятся только на первый взгляд, когда непонятно: куда происходит отправка, какие имена полей, что именно отправляется и т. д.

Но, на самом деле, все они сводятся к методам POST или GET. Чтобы понять, что именно отправляется, можно сохранить страницу с формой себе на диск и на кнопку отправки повесить функцию показа сформированных для отправки данных. Или ещё проще — как я, Wireshark’ом.

Если данные правильные, а аутентификация не происходит, то нужно копать в следующих направлениях:

  • задать верную строку реферера
  • задать «правильную» строку пользовательского агента.

Всё это можно сделать базовыми методами cURL, но я не буду на этом останавливаться. Урок получился и без того большим, а ведь я ещё хотел показать пару трюков с cURL.

Типсы и триксы cURL
cURL и получение кукиз помимо CURLOPT_COOKIEJAR

Думаю, уже стало понятно, что cURL правильно обрабатывает куки — сохраняет их, использует, когда сервер запрашивает, и т. д. Но иногда куки нужно сохранить. Для этого есть опция CURLOPT_COOKIEJAR, но воспользоваться ей можно не всегда. Этому и посвящён наш первый трюк.

Иногда из-за особенностей настройки PHP на сервере, нам недоступны такие опции как CURLOPT_COOKIEJAR (позволяет сохранить полученные куки в файл) и CURLOPT_COOKIEFILE (позволяет использовать куки из файла). Т.к. они говорят, что используя эти опции мы сможем стянуть любой файл с их сервера. Вот решение этой проблемы:

1) Не используем CURLOPT_FOLLOWLOCATION

2) Используем curl_setopt($ch, CURLOPT_HEADER, 1)

3) Собираем кукизы из заголовка header примерно так:

4) Задаём их используя curl_setopt($ch, CURLOPT_COOKIE, $cookies);

Второй совет. Из атакующих мы можем превратиться в жертву. Чтобы не стать жертвой атаки человек-по-середине, делаем так.

Пожалуйста, все, перестаньте устанавливать настройку CURLOPT_SSL_VERIFYPEER на false или 0. Если ваша установка PHP не имеет актуального комплекта корневых сертификатов CA, загрузите один на веб-сайте curl и сохраните его на ваш сервер:

http://curl.haxx.se/docs/caextract.html

Затем задайте путь в вашем файле php.ini file, например, на Windows:

Отключение CURLOPT_SSL_VERIFYPEER позволяет осуществить атаку человек-по-середине (MITM), а это нам не надо!

Ну и последняя на сегодня подсказка. Знаете ли вы, что возможно большое количество асинхронных запросов curl?

Для этого можно использовать

curl_multi_init

. Подробности и пример кода в официальной документации

http://php.net/manual/ru/function.curl-multi-init.php
Что ещё почитать про cURL

О cURL в PHP я бы рекомендовал официальную документацию — написано просто и много примеров.

http://php.net/manual/ru/ref.curl.php

Про cURL в командной строке

или

http://curl.haxx.se/docs/manual.html
Для чтения на русском языке также подготовлена вторая часть урока cURL: “Примеры команд cURL“.

RSERSH
13.03.2022 в 18:41

И всё-же, до меня что-то не доходит, зачем испльзовать именно php? Может дело втом, что я этот язык не знаю))? По этой причине, не совсем всё понимаю. Например: скриншот сделанный при неудачной попытке авторизации, сделан в браузере, но почему ошибка выводится в браузере, а не в консоли или ещё где-то? Я лично пытался всё через терминал сделать, которую хоть как-то знаю в отличие от php, в итоге ничерта не получилось. Может в этом проблема или это можно сделать и средствами терминала линукса, если да, то подскажите как?

Пытаюсьпримитивного бота собратьдля вк, но пока застрял на этом

cd Desktop;

curl -A “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.112 Safari/534.30”

https://vk.com

-o test.txt Не я не прошу за меня всё делать, просто пните в направлении, в котором нужно двигаться.

Login to remote site with php curl

Panama Jack Example not work for me – Give Fatal error: Call to undefined function build_unique_path(). I used this code – (more simple – my opinion) :

// options
$login_email = ‘[email protected]’;
$login_pass = ‘alabala4807’;
$cookie_file_path = “/tmp/cookies.txt”;
$LOGINURL = “http://alabala.com/index.php?route=account/login”;
$agent = “Nokia-Communicator-WWW-Browser/2.0 (Geos 3.0 Nokia-9000i)”;

// begin script
$ch = curl_init();

// extra headers
$headers[] = “Accept: */*”;
$headers[] = “Connection: Keep-Alive”;

// basic curl options for all requests
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);

// set first URL
curl_setopt($ch, CURLOPT_URL, $LOGINURL);

// execute session to get cookies and required form inputs
$content = curl_exec($ch);

// grab the hidden inputs from the form required to login
$fields = getFormFields($content);
$fields[’email’] = $login_email;
$fields[‘password’] = $login_pass;

// set postfields using what we extracted from the form
$POSTFIELDS = http_build_query($fields);
// change URL to login URL
curl_setopt($ch, CURLOPT_URL, $LOGINURL);

// set post options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS);

// perform login
$result = curl_exec($ch);

print $result;

function getFormFields($data)
{
if (preg_match(‘/()/is’, $data, $matches)) {
$inputs = getInputs($matches[1]);

return $inputs;
} else {
die(‘didnt find login form’);
}
}

function getInputs($form)
{
$inputs = array();
$elements = preg_match_all(“/(] >)/is”, $form, $matches);
if ($elements > 0) {
for($i = 0;$i $el = preg_replace(‘/s{2,}/’, ‘ ‘, $matches[1][$i]);
if (preg_match(‘/name=(?:[“‘])?([^”‘s]*)/i’, $el, $name)) {
$name = $name[1];

$value = ”;
if (preg_match(‘/value=(?:[“‘])?([^”‘s]*)/i’, $el, $value)) {
$value = $value[1];
}

$inputs[$name] = $value;
}
}
}

return $inputs;
}

$grab_url=’http://grab.url/alabala’;

//page with the content I want to grab
curl_setopt($ch, CURLOPT_URL, $grab_url);
//do stuff with the info with DomDocument() etc
$html = curl_exec($ch);
curl_close($ch);

var_dump($html);
die;

Автоматическая авторизация

Допустим, вы хотите парсить страницы,
доступные только авторизованному пользователю.

В этом случае алгоритм действий такой: первый запрос
отправляется на страницу авторизации сразу с POST данными,
при этом автоматически сессионные куки пишутся в файл,
а все остальные запросы отправляются на страницы, которые вы хотите парсить.


При этом на форму авторизацию шлется только первый запрос,
а потом можно спокойно парсить нужные страницы, отправляя
и получая при этом куки – так вы будете поддерживать сессию.

Учтите только, что сессия живет около 20 минут, если не обращаться к сайту.
То есть, если после последнего обращения к сайту пройдет больше времени,
то нужно авторизовываться заново.

Автоматическая запись и получение кук

Уже имеющиеся куки, это хорошо, но бывает очень редко.
Чаще всего нам нужно автоматически принимать и отправлять куки.
Это делается с помощью двух опций: CURLOPT_COOKIEFILE
командует принимать и сохранять куки в файл,
а CURLOPT_COOKIEJAR командует отправлять сохраненные куки на сервер:


Параметром эти опции принимают путь к файлу в который будут писаться куки.

Учтите нюанс: автоматическая отправка куки CURLOPT_COOKIEJAR работает
только при включенной опции CURLOPT_COOKIEFILE.

До php 5.5

$ch = curl_init('https://example.com');  
curl_setopt($ch, CURLOPT_POST, 1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, array('photo' => '@' . __DIR__ . '/image.png'); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$html = curl_exec($ch);
curl_close($ch);

С PHP 5.5 следует применять CURLFile.

$curl_file = curl_file_create(__DIR__ . '/image.png', 'image/png' , 'image.png');

$ch = curl_init('https://example.com');  
curl_setopt($ch, CURLOPT_POST, 1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, array('photo' => $curl_file));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);

Также через curl можно отправить сразу несколько файлов:

$curl_files = array(
	'photo[0]' => curl_file_create(__DIR__ . '/image.png', 'image/png' , 'image.png'),
	'photo[1]' => curl_file_create(__DIR__ . '/image-2.png', 'image/png' , 'image-2.png')
);

$ch = curl_init('https://example.com');  
curl_setopt($ch, CURLOPT_POST, 1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, $curl_files);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);

Ещё файлы можно отправить методом PUT, например так загружаются файлы в REST API Яндекс Диска.

$file = __DIR__ . '/image.jpg';
$fp = fopen($file, 'r');

$ch = curl_init('https://example.com');
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_UPLOAD, true);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file));
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
curl_close($ch);

Загрузка файлов

— самый распространенный инструмент для загрузки файлов посредством командной строки. Он входит в комплект большинства диструбутивов Linux. Однако в OSX его нет.

Команда wget url аналогична команде curl -OL url. Опция -О — это опция –remote-name, которая говорит curl сохранить тело ответа в локальном файле. Опция -L говорит curl следовать перенаправлениям.

Отправка post-запроса, содержащего json


Флаг

-X

говорит curl, какой метод следует использовать: PUT, POST и т.д. По-умолчанию curl использует метод GET, поэтому писать

curl -X GET

не нужно.

Флаг -X часто используется совместно с флагом -d, позволяющим добавить тело запроса. В следующем примере показано как отправить POST-запрос, содержащий некоторый json:

Отправка put-запроса, содержащего json-файл

Флаг

-d

также поддерживает отправку данных из локальных файлов.

Например, представим, что у нас есть файл data.js, содержащий такие данные:

Отправка авторизованного запроса


Заголовок авторизации используется для включения в запрос данных для авторизации при обращении к RESTful API. Для добавления указанных данных необходимо использовать флаг

-H

. Например, если ваш ключ интерфейса (API key)

my-secret-token

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

Предположим у вас уже есть название куки и ее значение.
В этом случае ее можно отправить на сервер с помощью
опции CURLOPT_COOKIE.


Давайте установим куку с именем name и значением ‘Дима’:

Работа с сессией

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

Сессии в PHP работают на основе кук. При старте
сессии в куку пишется переменная sessionid,
которая будет иметь что-то вроде такого значения 27za9c2lel3tk4zhhm7lmtzt6bbm3atj.
Поэтому, для работы сессий всего лишь необходимо получать
и отправлять куки на сайт, что мы и разобрали чуть выше.

Заключение

Резюмируя, вот опции curl, которые я нахожу самыми полезными:

Curl — полезный инструмент взаимодействия с API посредством командной строки, независимо от того, сторонний это API или API, который вы разрабатываете. Для быстрого тестирования curl подходит лучше, чем Axios в Node.js или настройка запроса в Postman, если вы знакомы с их синтаксисом.

Благодарю за потраченное время. Надеюсь, оно было потрачено не зря.

Похожее:  Server Installation and Configuration Guide

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *