Парсинг внешнего сайта на Yii 2.x (часть 1)

Иногда необходимо извлечь данные с сайта в автоматическом режиме, не прибегая к ручному копированию. Это может быть новостная лента, гороскоп, погода, программа телепередач и т.д. Рассмотрим пример на Yii2 и прокомментируем его.

Для реализации парсинга нам необходимо установить библиотеки Guzzle и phpQuery

Устанавливаем с помощью composer Guzzle (Guzzle работает с версией PHP 5.5 и выше)

composer require guzzlehttp/guzzle:~6.0

Используем следующую библиотеку для работы с phpQuery и устанавливаем ее так же с помощью Composer

composer require electrolinux/phpquery

Обновим composer

composer update

Для парсинга возьмем главную страницу Яндекса

В первом примере выведем всю страницу Яндекса, для этого в контроллере пишем следующий код

namespace app\controllers;

use Yii;
use GuzzleHttp\Client; // подключаем Guzzle
use yii\helpers\Url;

class YandexController extends \yii\web\Controller
{
    public function actionYandex {
        
        // создаем экземпляр класса
        $client = new Client();
        // отправляем запрос к странице Яндекса
        $res = $client->request('GET', 'http://www.yandex.ru');
        // получаем данные между открывающим и закрывающим тегами body
        $body = $res->getBody();
        // вывод страницы Яндекса в представление
        return $this->render('yandex', ['body' => $body]);
    }
}

Создадим файл-представление yandex.php и выведем страницу Яндекса

    echo $body;

Во втором примере выведем список новостей, для этого будем использовать phpQuery.

namespace app\controllers;

use Yii;
use GuzzleHttp\Client; // подключаем Guzzle
use yii\helpers\Url;

class YandexController extends \yii\web\Controller
{
    public function actionYandexnews {
        
        // создаем экземпляр класса
        $client = new Client();
        // отправляем запрос к странице Яндекса
        $res = $client->request('GET', 'http://www.yandex.ru');
        // получаем данные между открывающим и закрывающим тегами body
        $body = $res->getBody();
        // подключаем phpQuery
        $document = \phpQuery::newDocumentHTML($body);
        //Смотрим html страницы Яндекса, определяем внешний класс списка и считываем его командой find
        $news = $document->find(".b-news-list"); 
        // вывод списка новостей Яндекса с главной страницы в представление
        return $this->render('yandexnews', ['news' => $news]);
    }
}

Создадим файл-представление yandexnews.php и список новостей

    echo $news;

Пример третий. Выполним некоторые операции с полученными данными.

namespace app\controllers;

use Yii;
use GuzzleHttp\Client; // подключаем Guzzle
use yii\helpers\Url;

class YandexController extends \yii\web\Controller
{
    public function actionYandexnewslist {
        
        // создаем экземпляр класса
        $client = new Client();
        // отправляем запрос к странице Яндекса
        $res = $client->request('GET', 'http://www.yandex.ru');
        // получаем данные между открывающим и закрывающим тегами body
        $body = $res->getBody();
        // подключаем phpQuery
        $document = \phpQuery::newDocumentHTML($body);
        // получаем список новостей
        $news = $document->find("ul.b-news-list"); 
        // выполняем проход циклом по списку
        foreach ($news as $elem) {
            //pq аналог $ в jQuery
             $pq = pq($elem);
             // удалим первую новость в списке
             $pq->find('li.b-news-list__item:first')->remove();
             // выполним поиск в скиске ссылок
             $tags = $pq->find('li.b-news-list__item a');
             // добавим ковычки в начало и в конец предложения
             $tags->append('" ')->prepend(' "'); //
             // добавим свой класс к последней новости списка
             $pq->find('li.b-news-list__item:last')->addClass('my_last_class');
        }
        // вывод списка новостей яндекса с главной страницы в представление
        return $this->render('yandexnewslist', ['news' => $news]);
    }
}

Создадим файл-представление yandexnewslist.php и список новостей

    echo $news;

Это лишь малая часть возможностей phpQuery. Все возможные команды можно посмотреть на официальной странице phpQuery