Парсинг сайта с помощью CURL и phpQuery на PHP

Парсинг сайта с помощью CURL и phpQuery на PHPСегодня я расскажу про то, как парсить сайт спомощью библиотеки php CURL и библиотеки phpQuery.

phpQuery — это аналог jQuery, только на PHP. Все методы, которые есть в jQuery, должны присутствовать и этой библиотеке. Это удобно тем, что можно легко перемещаться по DOM дереву html документа и с легкостью находить нужные элементы.

Первым делом нам нужно получить html содержимое нужной страницы сайта для парсинга. Можно сделать это несколькими способами. Первый, самый простой — это использовать функцию file_get_content, указав url страницы в качестве параметра:

<?php
$page = file_get_contents('http://www.example.com/?param=1');
echo $page;
?>

Так же, в эту функцию есть возможность добавлять заголовки и т. д, с помощью использования потоковых контекстов:

// Создаем поток
$options = array(
  'http'=>array(
    'method'=>"POST",
    'header'=>"Accept-language: ru\r\n" .
              "Cookie: key=value\r\n"
  )
);

$context = stream_context_create($options); $file = file_get_contents('http://www.example.com/', false, $context);

Чтобы этот способ работал, опция allow_url_fopen в php.ini должна быть включена.

Так же получить содержимое web сайта можно с помощью сокетов (pfsockopen), но проще воспользоваться библиотекой php CURL, если она установлена на вашем сервере. Ниже я продемонстрирую, как получить содержимое страницы сайта с помощью библиотеки CURL.

Получение http страницы без параметров через CURL

$url = "http://example.com";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //Записать http ответ в переменную, а не выводить в буфер
$page = curl_exec($curl);

Получение http страницы с get параметрами:

$url = "http://example.com?param1=val1&param2=val2";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$page = curl_exec($curl);

Получение web страницы по протоколу https:

$url = "https://example.com";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, 0);
$page = curl_exec($curl);

Получение http страницы, которая загружается через редиректы (следование 302):

$url = "http://example.com";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1); //следование 302 redirect 
$page = curl_exec($curl);

Отправка POST запроса с помощью CURL:

$url = "http://example.com";
$curl = curl_init($url);
curl_setopt ($curl, CURLOPT_POST, 1);
$options = "param1=val1&param2=val2&param3=val3";
curl_setopt($curl, CURLOPT_POSTFIELDS,$options);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$page = curl_exec($curl);

Включаем куки в CURL запросе (нужно при парсинге личных кабинетов):

$url = "http://example.com";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_COOKIEJAR, "cookie.txt");
curl_setopt($curl, CURLOPT_COOKIEFILE, "cookie.txt");
$page = curl_exec($curl);

Включить в запросе GZIP сжатие (нужно, если тело ответа приходит в виде непонятного набора текста, то есть сервер отправляет сжатый gzip’ом текст):

curl_setopt($curl, CURLOPT_ENCODING, 'gzip');

Вывести заголовки ответа от сервера. Часто нужно для отладки, если сервер не присылает правильного тела ответа или не присылает его вообще:

curl_setopt($curl, CURLOPT_HEADER, 1);

Хочу отметить, что самым важными параметрами при парсинге являются:

curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1); //следование 302 редиректу
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
curl_setopt($curl, CURLOPT_COOKIEJAR, "cookie.txt");
curl_setopt($curl, CURLOPT_COOKIEFILE, "cookie.txt");

Стоит отметить, что все эти параметры (кроме первого) следует добавлять при необходимости. Поэксперементируйте с этими параметрами, если у вас не будет получаться без них. Так же не забывайте про параметр «CURLOPT_HEADER», он вам поможет при поиске проблемы.

Итак, что делать, если http страница получена через CURL, или каким-либо другим способом? Самое время воспользоваться phpQuery для парсинга полученного результата. Скачать библиотеку можно здесь.

<?php
include 'phpQuery.php';
   
//Получаем http страницу:
$url = "http://example.com";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //Записать http ответ в переменную, а не выводить в буфер
$page = curl_exec($curl);

//Обрабатываем переменную с помощью phpQuery:
$document = phpQuery::newDocument($page); //Загружаем полученную страницу в phpQuery
$hentry = $document->find('.item'); //Находим все элементы с классом "item" (селектор .item)

foreach ($hentry as $el) {
 $elem_pq = pq($el); //pq - аналог $ в jQuery
 $url = $elem_pq->attr('href');
 $text = trim($elem_pq->text());
 ...
}

Как мы видим phpQuery — это полный аналог jQuery.

Чтобы ознакомиться с полным наборов функций phpQuery, нужно зайти как ни странно, в документацию jQuery. Главная фишка phpQuery, как и jQuery — это использование css селекторов, это упрощает процедуру парсинга нужных элементов страницы в разы. Посмотреть методы и селекторы jQuery можно здесь.

Конечно, есть другие способы парсинга полученной с помощью php curl страницы, но парсинг при помощи phpQuery для меня наиболее удобен и эффективен.

Комментарии: 6 к “Парсинг сайта с помощью CURL и phpQuery на PHP”

  1. Вам не кажется тупым, что нельзя скопировать код? Хотел попробовать, но похоже придется найти этот пример на другом сайте.

    1. Если Вы о автоподстановке копирайта при копировании, то убрали функцию. 🙂

      1. Человеку, которому трудно скопировать текст с 1 страницы, curl точно не нужен 🙂

    2. Да, все верно. Но с установленным noscript — функция блокировки не срабатывает и можно все спокойно скопировать)

Добавить комментарий для Евгений Отменить ответ

Ваш адрес email не будет опубликован.