Парсим сайты с phpQuery

На моей практике довольно часто встречались задачи вроде: спарсить таблицу с какого-то сайта в csv-файл, сграбить картинки с какого-то сайта и т.д. Все эти задачи можно обобщить термином парсинг сайтов. Большинство из нас, как и я раньше для решения таких проблем использовали стандартные средства php для парсинга xml-файлов (html все-таки является подвидом xml) совместно с регулярными выражениями.

Скрипты получались довольно громоздкими и непонятными. К счастью для себя, я недавно наткнулся на библиотеку под названием phpQuery (https://code.google.com/p/phpquery/), которая является портированным jQuery в php.
Если Вы пользовались jQuery, то должны знать о его очень удобном механизме селекторов, который мог бы быть чрезвычайно полезным при парсинге сайтов.

Допустим у нас есть такой кусок кода:

<ol class="results" start="1">
...
<li>
<div class="title">
<i style="background-image: url(https://favicon.yandex.net/favicon/www.medvedev-da.ru);"/>
<a target="_blank" href="https://www.medvedev-da.ru/" onmousedown="w(this,'80.22.82','84=85,186=80');" tabindex="2">Дмитрий <b>Медведев</b> - Главная</a>
</div>
<div class="text">
<span>"Правительству нужно действовать незамедлительно, бегом!" - Итоги <wbr/>2008 года - взгляд Президента России Дмитрия <b>Медведева</b>.</span><br/>
</div>
<div class="info">
<span style="color: rgb(0, 102, 0);">
www.medvedev-da.ru
 · 9 КБ
</span>
</div>
<div class="info">
<nobr><a target="_blank" href="...">Сохраненная копия</a></nobr>
 ·  <nobr><a onmousedown="..." href="...">Еще с сайта</a> <span class="count">39241</span></nobr>
 ·  <nobr>Рубрика: <a href="..." onmousedown="w(this,'80.83','84=85');">Политика</a></nobr>
</div>
</li>
...
</ol>

Это код обычной страницы с результатами поиска Yandex`а по запросу “медведев”.
Нам нужно спарсить title страницы-результата, ее краткое описание и адрес страницы.
С помощью phpQuery, код будет примерно таким:

<?php
ini_set('max_execution_time', '0');
error_reporting(E_ALL);
define('URL', 'https://yandex.ru/yandsearch?text=медведев');
require('phpQuery.php');
$results_page = get_xml_page(URL);
$results = phpQuery::newDocument($results_page);
$elements = $results->find('ol.results > li');
$info = array();
foreach ($elements as $element){
 $title = pq($element)->find('div.title > a');
 $title = pq($title)->text();
 $descr = pq($element)->find('div.text > span');
 $descr = pq($descr)->text();
 $link_text = pq($element)->find('div.info:first > span');
 $link_text = pq($link_text)->text();
 $link_text = explode('•', $link_text);
 $link = trim($link_text[0]);
 $info[] = array('title' => $title, 'descr' => $descr, 'link' => $link);
}
print_r($info);
function get_xml_page($url) {
 $ch = curl_init($url);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 $page = curl_exec($ch);
 curl_close($ch);
 return $page;
}
?>

Как видите, код довольно понятный и его можно очень легко модифицировать при необходимости. Что касается самой библиотеки phpQuery, в этой статье я рассмотрел лишь часть ее возможностей на примере парсинга сайтов. На самом деле, с ее помощью можно так же легко модифицировать структуру документа html и еще много другого.
Более подробную документацию к ней можно найти в блоге ее разработчика: https://phpquery-library.blogspot.com/.

На этом все. Удачи! :)

P.S.:

В связи с переездом FeedBurner`а в Google, адрес нашей RSS-ленты изменился на [ссылка]. Измените его в Ваших ридерах если уже подписаны и подписывайтесь на него в противном случае :) Повторяю: Новый адрес нашего RSS-фида - [ссылка].





Читайте также:



26 Ответов на “Парсим сайты с phpQuery”

  1. […] удобно, практично. А вчеру увидел порт jQuery на php. Вот тут хороший пример использования библиотеки. Рубрика: […]

  2. adw0rd

    https://i-novice.net/zheltaya-knopka-rss/
    >Наш адрес - [ссылка].

    исправьте :)

  3. cryptus

    2 adw0rd: Спасибо. Я и забыл про эту страницу :)

  4. Integrable

    Спс, не знал про такое. Сам странички парсил с помощью Snoopy

  5. Igor

    Актуально

  6. shureg

    еще есть не плохая софтинка webharvest опенсурс.
    быстро и удобно
    это тоже интерессный вариант, надо попробовать

  7. Саша

    Классная вещь.
    У меня один вопрос :
    Яндекс он в utf-8 выдает результаты поиска.
    А если сайт в win-1251 , то у меня кракозябры выскакивают.

  8. novice

    Посмотрите в сторону функции iconv

  9. Если будете часто парсить, можно на бан по IP влететь ) Я уже пару раз влетел.

  10. gendalf

    ктонибудь сравнивал скорость парсинга на phpQuery с регекспами?

  11. TomDeLonge

    Что то не работает код, может структура Яндекса поменялась?(

  12. cryptus

    Вполне возможно, но лучше включить вывод ошибок и проверить нет ли какой-то ошибки или предупреждения.

  13. TomDeLonge

    А разве строка error_reporting(E_ALL); не говорит выводить все ошибки и предупреждения?
    Ошибок нету, просто массив пустой(

  14. Олег

    чтот ругается…
    Fatal error: Call to undefined function curl_init()

  15. novice

    Олег, Вам нужно подключить модуль cURL в php.ini:
    extension=php_curl.dll

  16. Олег

    Спасибо за ответ. Потом пришлось еще и dom включать…

    Теперь не могу понять, как настроить. На удаленном источнике нет id вообще. Там верстка только таблицы и классы.
    Что можно писать в find ? Какой синтаксис?

    Пишу
    $elements = $results->find(‘table’); //

    $title = pq($element)->find(‘a’);
    $title = pq($title)->text();

    это не работает

  17. cryptus

    Синтаксис параметра find очень похож на селекторы в css и jquery. Ознакомься с ним и заодно используй команду echo в php, для вывода промежуточных результатов.

  18. Скрипт выдаёт ошибку:

    Fatal error: Call to undefined function curl_init()

    как исправить???

  19. novice

    К PHP не подключена библиотека CURL, поэтому выдается такая ошибка.

  20. Александр

    Что б не было кракозябр с яндекса в начало страницы
    header(‘Content-type: text/html; charset=utf-8′);

  21. 1datr

    Html не является подвидом xml. Подвидом xml является xhtml.

  22. Вячеслав

    А что будет если в коде сайта есть ошибки, например неправильно вложенные теги (…)?
    Парсер “ниасилит”?

  23. Антон

    так и не нашел документации. пытаюсь найти аналог метода в jQuery “attr”, пока безуспешно

  24. Вася

    Даний скрипт создает масив значений што делать эсли нужна заливать в базу все промежуточние значения а не масив целиком.

  25. DoctorX

    Весьма интересная библиотека. На ней написал парсер для сайта. Но посмотрев код решил ждать пока его приведут до ума. Там куча недописанного и не доделаного. Так что DOM парсером пхп и вперед. С надеждой на то, что автор библиотеки его допилит и можно со спокойной душой будет юзать.

  26. Петя

    Можно ли как-то настроить чтобы парсинг осуществлялся регистронезависимый, а то если указать
    “find(‘meta[name=”keywords”]’)”
    а на странице будет Keywords (c большой буквы) то он не найдет. Strtolower всего контента - не пойдет.


© Copyright. . I-Novice. All Rights Reserved. Terms | Site Map