Вы когда-нибудь хотели собрать цены с сайтов конкурентов, вытащить контакты с доски объявлений или просто автоматизировать сбор данных для своего проекта? Если да, то парсинг — это то, что вам нужно. И PHP — отличный инструмент для этой задачи, несмотря на то, что многие считают его устаревшим. В этой статье я расскажу, как с помощью PHP парсить сайты, какие библиотеки использовать и как не наступить на грабли.
Ссылка на оригинальную статьюЧто такое парсинг и зачем он нужен
Парсинг — это автоматический сбор данных с веб-страниц. Представьте, что вы вручную копируете информацию из сотен сайтов — это займёт часы. А парсер делает это за минуты. Например, вы хотите узнать среднюю цену на айфон у разных продавцов. Вместо того чтобы обходить каждый сайт, вы пишете скрипт, который сам заходит на страницы, вытаскивает цены и сохраняет их в таблицу.
PHP для этого подходит идеально: он прост, у него есть мощные библиотеки для работы с HTTP и HTML, а также большое сообщество. Даже если вы новичок, разобраться будет несложно.
Основные инструменты для парсинга на PHP
Чтобы начать парсить, вам понадобятся два ключевых компонента: клиент для отправки HTTP-запросов и библиотека для разбора HTML. В PHP есть несколько популярных вариантов, и я расскажу о самых удобных.
| Библиотека | Что делает | Когда использовать |
|---|---|---|
| cURL | Отправляет HTTP-запросы, поддерживает cookies, заголовки, прокси | Если нужно получить содержимое страницы с учётом сессий или заголовков |
| Guzzle | Более высокоуровневая библиотека на основе cURL, удобный API | Если нужен удобный код с обработкой ошибок и асинхронными запросами |
| Symfony DomCrawler | Разбирает HTML-код, позволяет искать элементы по CSS-селекторам и XPath | Для извлечения данных из HTML-структуры |
| phpQuery | Портирует jQuery на PHP, удобен для поиска элементов | Если привыкли к jQuery-стилю работы с DOM |
| Simple HTML DOM | Лёгкая библиотека для парсинга, простая в использовании | Для простых задач, когда не хочется подключать тяжёлые зависимости |
Я советую начать с комбинации Guzzle и Symfony DomCrawler — они мощные и хорошо документированы. Но для простых примеров подойдёт и Simple HTML DOM.
Как написать простой парсер: пошаговый пример
Давайте напишем парсер, который будет собирать заголовки статей с сайта. Для этого нам понадобится PHP, установленный на вашей машине, и Composer — менеджер пакетов. Если Composer ещё не установлен, скачайте его с официального сайта.
Сначала создадим проект и установим нужные библиотеки. Откройте терминал и выполните:
composer require guzzlehttp/guzzle symfony/dom-crawler symfony/css-selector
Теперь создадим файл parser.php и напишем код:
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use Symfony\Component\DomCrawler\Crawler;
$client = new Client([
'timeout' => 10,
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
]
]);
$url = 'https://example.com/blog';
try {
$response = $client->request('GET', $url);
$html = $response->getBody()->getContents();
} catch (Exception $e) {
die('Ошибка загрузки страницы: ' . $e->getMessage());
}
$crawler = new Crawler($html);
$crawler->filter('h2.article-title')->each(function (Crawler $node) {
echo $node->text() . PHP_EOL;
});
Разберём, что здесь происходит. Мы создаём HTTP-клиент с заголовком User-Agent, чтобы сайт не принял нас за бота. Затем загружаем страницу и передаём HTML в DomCrawler. С помощью метода filter мы ищем все элементы h2 с классом article-title и выводим их текст.
Обработка данных: как извлечь нужное и не сломаться
Просто вывести текст заголовков — это хорошо, но в реальной жизни нужно больше: сохранить данные в базу, отфильтровать, обработать. Давайте рассмотрим, как можно улучшить парсер.
Допустим, мы хотим собирать не только заголовки, но и ссылки на статьи, а также даты публикации. Для этого нужно изучить структуру HTML-страницы. Откройте сайт в браузере, нажмите правой кнопкой мыши и выберите «Просмотреть код». Найдите нужные элементы и определите их селекторы. Например:
<div class="post">
<h2 class="title"><a href="/article/1">Заголовок статьи</a></h2>
<span class="date">2025-03-15</span>
</div>
Теперь мы можем написать такой код:
$crawler->filter('.post')->each(function (Crawler $node) {
$title = $node->filter('.title a')->text();
$link = $node->filter('.title a')->attr('href');
$date = $node->filter('.date')->text();
echo "$title ($date) - $link" . PHP_EOL;
});
Здесь мы для каждого блока .post получаем заголовок, ссылку и дату. Обратите внимание: если элемент не найден, DomCrawler выбросит исключение. Чтобы этого избежать, можно проверять наличие элемента:
if ($node->filter('.date')->count() > 0) {
$date = $node->filter('.date')->text();
} else {
$date = null;
}
Это надёжнее, чем предполагать, что все элементы всегда на месте.
Продвинутые техники: пагинация, прокси и обход блокировок
Когда вы парсите большой сайт, рано или поздно столкнётесь с пагинацией — когда контент разбит на страницы. Например, на сайте 50 страниц со списком товаров. Ваш парсер должен уметь переходить по всем страницам. Для этого можно использовать цикл:
for ($page = 1; $page <= 5; $page++) {
$url = "https://example.com/products?page=$page";
// загружаем и парсим страницу
}
Однако будьте осторожны: слишком частые запросы могут привести к блокировке. Вот несколько советов, как этого избежать:
- Добавьте задержку между запросами с помощью
sleep(1)илиusleep(500000). - Используйте ротацию User-Agent и прокси-серверов.
- Уважайте файл robots.txt — он указывает, какие страницы можно парсить.
- Если сайт требует авторизацию, используйте cookies и сессии.
Также часто встречаются сайты, которые подгружают данные через JavaScript. В этом случае просто получить HTML недостаточно — нужно выполнить JS. Для этого можно использовать библиотеку Puppeteer или php-webdriver, но это уже более сложный уровень. Если вы новичок, начните с простых сайтов.
Типичные ошибки и как их избежать
Начинающие парсеры часто наступают на одни и те же грабли. Вот список самых частых ошибок:
| Ошибка | Решение |
|---|---|
| Не указывают User-Agent | Всегда задавайте заголовки, имитирующие браузер |
| Неправильный селектор | Используйте инструменты разработчика в браузере, чтобы точно определить селектор |
| Не обрабатывают ошибки сети | Оберните запросы в try-catch и добавьте логирование |
| Слишком быстрые запросы | Добавьте задержки и ограничьте количество запросов в секунду |
| Парсят страницы с JS-контентом без эмуляции | Используйте headless-браузеры или сделайте запрос к API, который отдаёт данные |
Также не забывайте про кодировку. Если сайт в UTF-8, а вы выводите данные в консоль Windows, могут быть проблемы с отображением кириллицы. Используйте mb_convert_encoding() для преобразования.
Что в итоге
Парсинг на PHP — это реально и не так сложно, как кажется. С помощью библиотек Guzzle и DomCrawler вы можете собрать данные с большинства сайтов. Главное — соблюдать этикет: не перегружать сервер, уважать robots.txt и не нарушать законы о персональных данных.
Начните с простого: напишите парсер для небольшого сайта, потренируйтесь на селекторах, добавьте обработку ошибок. А когда почувствуете уверенность, переходите к более сложным задачам — пагинация, авторизация, прокси.
Помните: парсинг — это мощный инструмент, но используйте его ответственно. И если что-то не работает — не сдавайтесь, в интернете много примеров и сообществ, готовых помочь.
Удачи в ваших проектах!
Студия WNDER



