Скрапинг с Goutte (crawler). Парсинг сайтов с использованием библиотеки Goutte.

04.04.2022
Содержание:

В новой записи я вам покажу как работать с библиотекой для парсинга — Goutte (crawler). Я вам покажу как забирать информацию со стороннего сайта, переходить по ссылкам и автоматически отправлять формы на сайте.

Полная документация тут — https://symfony.com/doc/current/components/dom_crawler.html

Ссылка на библиотеку — https://github.com/FriendsOfPHP/Goutte

Подключение библиотеки Goutte и создание запроса на сайт

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

/* подключаем файлы полученные через Composer */
require __DIR__ . "/vendor/autoload.php";

use Goutte\Client;
use Symfony\Component\HttpClient\HttpClient;

/* создаём объект и делаем запрос на сайт Prog-Time */
$client = new Client();
$crawler = $client->request('GET', 'https://prog-time.ru/');

Получение текстовой информации с помощью Goutte

$crawler->filter('.bottom_list_last_posts .home_link_post .home_heading_post')->each(function ($node) {
    var_dump($node->text());
});

Получение атрибута href ссылки

$crawler->filter('.bottom_list_last_posts .home_link_post')->each(function ($node) {
    var_dump($node->attr("href"));
});

Получение атрибута src изображения

$crawler->filter('.bottom_list_last_posts .home_link_post img')->each(function ($node) {
    var_dump($node->attr("src"));
});

Фильтрация выборки (выборка элементов через один)

Используйте метод reduce для указания функции для фильтрации выборки. В моём примере указана функция которая задаёт порядок «через 1» и «каждый десятый элемент».

$newListLinks = $crawler
    ->filter('.home_link_post .home_heading_post')
    ->reduce(function ($node, $i) {
	return ($i % 2) == 0;
	// return ($i % 10) == 0;
    })
    ->each(function ($node) {
	var_dump($node->text());
    });

Получение элемента указанного порядка

С помощью метода eq вы можете указать номер элемента. Нумерация идёт с 0, поэтому в моём примере и мы получим 4 элемент с классом «home_heading_post«

$itemPost = $crawler->filter('.home_link_post .home_heading_post')->eq(3);
var_dump($itemPost->text());

Получение первого и последнего элемента

first() — возвращаем первый элемент
last() — возвращает последний элемент

$firstItem = $crawler->filter('.home_link_post .home_heading_post')->first();
$lastItem = $crawler->filter('.home_link_post .home_heading_post')->last();

var_dump($firstItem->text());
var_dump($lastItem->text());

Получение соседнего элемента на уровне в дереве DOM

siblings() — возвращает соседние элементы в дереве DOM

$siblingsItem = $crawler->filter('.home_link_post .home_heading_post')->eq(3)->siblings();
var_dump($siblingsItem->text());

Получение ссылки по тексту и нажатие на ссылку

С помощью метода selectLink() получаем ссылку по тексту внутри ссылки, текст указывается в качестве параметра для метода selectLink().

С помощью метода link() переходим по ссылке и получаем новую страницу.

С помощью метода getUri() получаем URI ссылки

$linkPost = $crawler->selectLink('Парсинг на PHP с формированием данных в Excel');
$link = $linkPost->link();
vardump($link);

$uri = $link->getUri();
var_dump($uri);

Получение объекта изображения

$imagesPost = $crawler->selectImage('Парсинг на PHP с формированием данных в Excel');
$image = $imagesPost->image();

var_dump($image);

Получение дочерних элементов

$childrenItems = $crawler->filter('.header_post_list')->children();
vardump($childrenItems);

Отправка формы с помощью Goutte

/* получаем страницу с формой */
$crawler = $client->request('GET', 'https://prog-time.ru/test_form.php');

/* находим кнопку для отправки формы */
$form = $crawler->selectButton('Отправить')->form();

/* передаём параметры формы и отправляем запрос */
$crawler = $client->submit($form, [
    'name' => 'Илья',
    'phone' => '+7(999)999-99-99',
]);
На этом всё!
Больше интересных статей в нашей группе - https://vk.com/progtime
Вы так же можете разместить свой вопрос на нашем форуме, где другие программисты смогут вам помочь в решение вашей задачи - https://vk.com/prog_time
Так же прокачивайте свои навыки на нашем канале - https://www.youtube.com/c/ProgTime
Наши планы
  • Написание материала для курса по разработке ботов на Telegram
  • Разработка универсального парсера на PHP

Поддержите мой сайт!

Каждый переведённый донат, мотивирует на создание новых записей и уроков на YouTube