Парсинг сайтов. Библиотека phpQuery

» »


Парсинг сайтов. Библиотека phpQuery

Привет, друзья! Открываем тему парсинга данных, так как тема достаточно актуальна. Например, вам нужно спарсить с какого-то сайта курсы валют или информацию о погоде, или ещё какие-нибудь данные. И вам здесь необходимо парсить данные с того или иного сайта, или с набора сайтов.

 

Как мы можем решить эту задачу? Можем решить её в лоб с помощью регулярных выражений. Однако, это решение не всегда может быть достаточно простым, поскольку сайты бывают разные, и вытащить с них информацию с помощью регулярных выражений бывает достаточно тяжело.

 

И здесь нам на помощь приходят всевозможные библиотеки, одна из которых библиотека phpquery. Здесь мы рассмотрим один небольшой пример работы.

 

Итак, перед нами стоит задача – выбрать какой-нибудь сайт, и мы выберем один из популярнейших сайтов банков – сайт Приватбанка. Нам, к примеру, нужно вытащить отсюда курс валют. Кстати, у каждого банка есть своё API, которое мы можем использовать и получать эти курсы валют, но представим себе, что API нет. И нам нужно распарсить табличку и получить курсы валют.

 

Прежде, чем приступать к парсингу данных, мы должны изучить те самые данные, с которыми будем работать. То есть, данные, которые находятся в табличке, и если откроем код, то это будут данные с идентификатором course. Для того, чтобы вытащить все данные, мы должны получить контент страницы. Сделать это можно, воспользовавшись, к примеру, функцией file_get _contents. Создаём файл index.php.

 

Для этого мы в переменную url поместим сначала адрес, с которым будем работать, и получим её контент-страницы в переменную file в функции file_get _contents. Давайте убедимся, что у нас всё работает, что мы получили искомый контент.

 

header(‘Content-type: text/html; charset=utf-8’);
$url=”https:privatbank.ua/”;
$file= file_get _contents($url);
echo htmlspecialchars($file);

 

Теперь нам нужно из кода добавить блок table id=course-table-pb. Чтобы его вытащить, нам нужно создать регулярное выражение. Давайте его поместим в переменную pattern, и выглядеть оно будет таким образом:

 

pattern=’#
#’;

 

Для этого мы создаём переменную pattern и помещаем в неё наш шаблон. Ставим ограничения шаблона в виде #, а затем добавляем содержимое  таблицы. Начало таблицы

. И снова в конце добавляется ограничитель шаблона #. Всё это мы поместили в одинарные кавычки. Чтобы не захватывались другие таблицы, мы должны сделать не жадным квантификатор - ? ( он обозначен в виде знака вопроса). Вот теперь проверяем, как всё работает.

Используем функцию preg_match. Первым параметром идёт наш pattern, вторым параметром file – искомый документ, и в переменную matches мы положим то, что нашли.

preg_match($pattern,$file,$matches);

Давайте убедимся, что всё у нас работает, как нужно:

print_r_($matches);

Выдаёт ошибку. Смотрим внимательно. Здесь у нас точка в шаблоне – она по умолчанию совпадает с любым символом, кроме переноса строки. А поскольку наша табличка в исходном коде содержит переносы строк, то для этого мы должны в конце добавить модификатор s, и точка у нас совпадёт с любым символом, включая перенос строки.

pattern=’#
#s’;

 

Теперь мы видим, что получили нужные данные.

 

header(‘Content-type: text/html; charset=utf-8’);
$url=”https:privatbank.ua/”;
$file= file_get _contents($url);
pattern=’#
#s’;preg_match($pattern,$file,$matches);print_r_($matches);

 Это всё не сложно, но если нам нужны какие-то конкретные данные: курс евро, покупка или продажа доллара и другие, то здесь уже всё сложнее, потому что, если мы посмотрим исходный код, то в коде соответствующие ячейки не имеют ни класса, ни модификатора.

В принципе вытащить их из кода можно. Здесь на помощь нам приходят всевозможные библиотеки для таких сложных задач. И одна из таких библиотек – это библиотека phpquery.

В чём её удобство? Удобство в том, что библиотека phpquery использует все те же самые методы и способы выбора элементов и работы с ними, что и библиотека JQuery. Они очень-очень похожи. Мы в этом убедимся, познакомившись с возможностями данной библиотеки. Она позволяет не только получить какие-то данные, распарсить её, но и позволяет прямо на лету что-то сделать с этими данными. Что-то заменить в этих данных, что-то удалить из этих данных, оставить только что-то конкретное и т.д.

Для того, чтобы использовать данную библиотеку, нам необходимо её скачать. Для этого переходим по ссылке download на сайт https://code.google.com/archive/p/phpquery/. Скачиваем последнюю актуальную версию и подключаем.

 header(‘Content-type: text/html; charset=utf-8’);
require ‘phpQuery.php’;

Для того, чтобы начать работать с библиотекой phpQuery, мы должны создать объект данной библиотеки. Делается это следующим образом. Добавляется переменная doc, и в phpQuery мы вызываем статический метод newDocument, а в качестве параметра мы передаём считанный контент, который находится у нас в переменной файла.

$doc = phpQuery::newDocument($file);

Теперь мы можем посмотреть, что у нас находится в переменной doc.

var_dump($doc);

Как видим, это объект phpQuery. Дальше нам следует найти ту самую таблицу с идентификатором course_table_pb. Как это делается?

Здесь не нужно ни составлять регулярное выражение, ни продумывать, как вытащить из контента искомый элемент. Нам нужно использовать методы данной библиотеки phpQuery. В частности, это может быть метод find. Он ищет в дом-дереве соответствующий элемент.

Давайте так и поступим. Пусть у нас будет переменная $tbl. Обращаемся к нашему объекту и вызываем метод find и в качестве параметра передаём элемент с искомым идентификатором. И всё. Никаких регулярных выражений нам при этом не нужно абсолютно.

$tbl= doc->find(‘#course-table-pb’);
echo $tbl;

Мы получили тот же результат. Но при этом не пришлось составлять регулярное выражение, за нас фактически сделала всё библиотека.

Теперь попробуем усложнить нашу задачу и постараемся вытащить какой-то конкретный курс валюты, например, доллара. Смотрим снова исходный код. Что нам здесь нужно?

Нам нужен код body с идентификатором. Внутри таблицы нам понадобится строка, которая идёт третьей по счёту. Здесь мы используем метод eq. Он есть и в JQuery, он может посчитать элементы. Нумерация начинается с нуля. Поэтому нам нужен tr, который идёт третьим, следовательно, с индексом 2 (0-1-2). Внутри строки tr мы ищем ячейку с индексом 1. Если нумерация начинается с ноля, то здесь индекс получается 1(0-1)

$tr = $doc->find('#selectByPb tr:eq(2) td:eq(1);');

В данном примере мы получили только код одной ячейки. Но если нам нужен только текст, то используем метод text, который используем аналогично.

С помощью phpQuery сложные задачи решаются очень легко.

Рабочий пример можно посмотреть по ссылке:
https://cloud.mail.ru/public/4U7L/Bes3cE9Tv
А мы ждём вас на следующем уроке.

 


Друзья! Приглашаем вас к обсуждению. Если у вас есть своё мнение, напишите нам в комментарии.