Долгое время я вынашивал идею написать что-нибудь по теме парсинга контента, и вот решился! Начнём с самого тривиального, а потому, востребованного примера – парсинга новостей в рунете. Мы воспользуемся самым простым способом, который есть в PHP и разберем его максимально подробно. В дальнейшем это позволит нам написать более интересные вещи.
Для чего же ещё нам может понадобиться парсер новостей? И тут, честно говоря, вариантов достаточно, чтобы уделить время этой теме. Вот несколько примеров, которые я могу привести исходя из своего опыта.
Так как я в последние время работаю с интернет-магазинами, то стандартная задача от клиента, который только что зарелизил свой магазин или только собирается это сделать - наполнение каталога актуальными товарами, т.е. изображениями, ценами, описаниями товаров и т.д... Вручную это делать бессмысленно, для этого мы можем использовать сайт близкий по тематике, а необходимый контент оттуда спарсить.
Второй пример будет касаться сегодняшней темы – это парсер новостей. Представьте ситуацию, когда необходимо отслеживать изменения новостей и появление новых на десятке различных сайтов по определённым ключам, и транслировать их своим посетителям. К примеру, такой популярный новостной портал как tjournal использует для этого своих роботов или, проще говоря, скрипты, которые парсят новостные ленты и самое интересное отображают у себя.
Основной принцип написания парсера, а в нашем случае парсера новостей – это получить страницу со стороннего ресурса, вытянуть из нее необходимый контент и обработать его. И вся ирония, заключается в том, что не всегда приходит, то, что мы ожидаем. Как с этим бороться мы рассмотрим в других статьях, а сегодня возьмем идеальный вариант и попробуем спарсить новостную ленту Яндекса на главной странице.
Первое, что мы должны сделать, это проанализировать HTML разметку и посмотреть, где находятся нужные нам новости:
Все записи лежат в двух списках. Первый это видимый, а второй скрытый для эффекта смены. Сама же новость обернута ссылкой:
После того, как мы получим страницу, нам потребуется вытянуть все эти ссылки, у которых мы возьмем текст и значение атрибута href.
Какие же инструменты и библиотеки нам потребуются для этого? Во-первых, сам механизм для получения контента со стороннего ресурса, сегодня я использую для этого функцию file_get_contents(). Во-вторых, библиотека для разбора контента, одна из известных и удобных - phpQuery.
Итак, приступим, в качестве сервера использовать я буду opensever, где создам новый сайт parser.loc, куда через composer установлю библиотеку phpQuery. Делается это довольно просто, открываем консоль (можно воспользоваться консолью нашего сервера):
Перейдем в папку с нашим сайтом:
cd domains/parser.loc
Теперь нужно установить phpQuery, найти нужный пакет можно на сайте packagist:
Вернемся в консоль и установим пакет, а следом создадим файл index.php и завершим работу с консолью:
composer require electrolinux/phpquery
copy con index.php
Всё, что нам нужно для работы мы подготовили, теперь приступим к написанию кода и в исполняемый файл подключим библиотеку:
require_once("vendor/autoload.php");
Далее вытянем страницу и сразу отобразим её для проверки:
$html = file_get_contents("https://yandex.ru/");
echo($html);
Самый главный этап мы сделали, осталось спарcить названия новостей и их ссылки, для удобства результат можно поместить в массив:
phpQuery::newDocument($html);
$links = pq("#tabnews_newsc")->find("a");
$tmp = array();
foreach($links as $link){
$link = pq($link);
$tmp[] = array(
"text" => $link->text(),
"url" => $link->attr("href")
);
}
phpQuery::unloadDocuments();
Работа с DOM деревом phpQuery схожа с jQuery. Поэтому эта библиотека очень хорошо подходит для задачи разбора страницы, конечно можно использовать и другие инструменты, но зачем? Вкратце, что тут происходит: полученную страницу мы передаем методу newDocument(), как итог мы получаем объект документа, с которым далее и работаем. Очень важно в конце всех манипуляций удалить его из памяти! Делается это при помощи метода unloadDocuments(). Вытянуть новости не особо ресурсозатратная операция, но если вы решили спарсить пару сотен страниц и их обработать, то вы ощутите всю необходимость подчищать память. В phpQuery функция pq() соответствует функции из jQuery $(). Поэтому внутри, по аналогии, мы втягиваем все ссылки и сохраняем их в массив. Для визуализации давайте отобразим их на странице:
<ul>
<?php foreach($tmp as $value): ?>
<li>
<a href="<?php echo($value["url"]); ?>" target="_blank">
<?php echo($value["text"]); ?>
</a>
</li>
<?php endforeach; ?>
</ul>
Вот и всё! Наш парсер новостей на PHP готов. Сегодня мы рассмотрели самый быстрый способ, но для того, чтобы спарсить более сложные страницы file_get_contents() не подойдет, мы можем при желании передать и заголовки при обращении на страницу донора, но если там установлен редирект, нам будет необходимо это отслеживать и следовать за ним. Эта функция больше подходит для работы с различными API. Для написания более универсального парсера можно воспользоваться CURL, где многие вещи сделать удобнее, но об этом мы поговорим в одной из следующих статей.