PHP. Библиотека PHPQuery


Есть один очень удобны и полезный инструмент, которым мне нравится пользоваться это jQuery. И больше всего мне нравится его поиск селекторов в документе.
Для того что бы найти элемент дерева с  id = "mydiv" необходимо выполнить $("#mydiv")
или же к примеру что бы найти все элементы с классом class="myclass"  достаточно $(".myclass")
Это очень удобно! И очень мало кода! Вот она красота!

Но что делать когда возникает необходимость парсить сайты?  То есть получить с другого сайта определенную информацию, не загружая весь сайт.

Я очень уважаю компанию mail.ru за то какой они вклад делают в развитие рунета, и по этому я люблю читать их блог на хабре, но порой охота видеть минимальное количество информации, без ненужных элементов и т.д. К примеру на планшете с 3G модема, что бы не грузить много информации.

И тут на помощь приходит PHPQuery. Доступна тут: phpQuery

Собственно для примера работы напишем небольшой скрипт для получения записей с блога mail.ru
делаем файл index.php

и первым делом подключаем саму библиотеку

require_once 'lib/phpQuery/phpQuery.php';

к примеру в будущем нас будут интересовать не только блоги mail.ru. Заведем переменную

$blog='mailru';

и ссылка которая получится будет выглядеть так

$url='http://habrahabr.ru/company/'.$blog.'/blog/';

то есть по данным хранящимся в $url находится интересующий нас блог.
Теперь загрузим страницу которую будем скармливать библиотеке phpQuery

$habrablog=file_get_contents($url);

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


как видим все блоки размещены в одном DIV с классом "company_blog"
Если бы использовали jQuery, то что бы найти этот узел использовали $(".company_blog")
Но мы имеем дела с PHPQuery
Поэтому с начало подготовим документ для работы.

$document=phpQuery::newDocument($habrablog);

Теперь у нас есть подготовленная структура, которая является родной для phpQuery.
Вот теперь мы можем использовать все удобства.
Давайте получим все посты на загруженной странице.
Если бы использовали jQuery то выглядело бы это так:

var posts=$(".company_blog").find("DIV.posts");

удобно и мало кода. Но мы пишим на PHPQuery

$hentry=$document->find('div.company_blog > div.posts');

вот после этого все узлы с классом POSTS будут у нас в переменной $hentry
Код не сильно отличается от jQuery.

Теперь переберем все элементы POSTS и приведем их к удобному нам виду

foreach ($hentry as $el){
    $pq=pq($el);
    $pq->find('div.published')->remove();
    $pq->find('div.hubs')->remove();
    $pq->find('div.infopanel_wrapper')->remove();
}


Тут надо сказать пару слов о PQ(...), это фактически $ в jQuery, по этому везде в место знака доллара используем функцию PQ();
Мы удалили лишние узлы, которые ненужны для нашей верстки.

И наконец выведем в раузер что у нас осталось

echo $hentry;

Вот красота!


Ниже расположен код для любителей копипаста

<?php
require_once 'lib/phpQuery/phpQuery.php';

$blog='mailru';
$url='http://habrahabr.ru/company/'.$blog.'/blog/';

//Загрузили документ
$habrablog=file_get_contents($url);

$document=phpQuery::newDocument($habrablog);

//получаем данные с DIV класса company_blog
$hentry=$document->find('div.company_blog > div.posts');

foreach ($hentry as $el){
    $pq=pq($el);
    $pq->find('div.published')->remove();
    $pq->find('div.hubs')->remove();
    $pq->find('div.infopanel_wrapper')->remove();
}

echo $hentry;

2 комментария:

  1. Подскажи, почему $hentry=$document->find('p'); собирает абзацы, но при этом они находятся в одной строке а не а массиве? т.е. я не могу провести по ним перебор с помощью foreach

    ОтветитьУдалить
    Ответы
    1. Для отладки попробуй сначала вывести через print_r($hentry); что бы посмотреть что, да как именно внутри.
      Но при использовании phpQuery на документы валидные html
      конструкция
      $document=phpQuery::newDocument( html текст )
      $h=$document->find(условие)
      возвращает набор элементов, которые соответствуют условию поиска
      и перебераются
      foreach($h as $el){
      echo '--------
      ';
      echo $el;
      echo '--------
      ';
      }

      Удалить