Выбор парсера SimpleHTML, Nokogiri, phpQuery

Хоть раз в своей жизни парсингом сайта занимались почти все веб программисты. Задачи для парсинга могут быть самые разные, от получения товаров из каталога, до валидации страниц. Я думаю изначально большинство моих коллег пишут парсеры на регэкспах(регулярных выражениях, что позволяет написать парсер небольших сайтов или страниц довольно быстро. Однако такой парсер будет очень чувствителен к разметке и  даже незначительное изменение в разметке может привести к остановке парсинга.А потому, этот процесс сильно облегчит парсер.

После прохождения этапа написания парсера на рэгекспах я приступил к поиску подходящей библиотеки. После первой «волны» поисков я натолкнулся на Nokogiri.

Nokogiri

Адрес: https://github.com/olamedia/kanon/tree/master/src/parse

О сколько времени я с ней работал и до сих пор не понял почему.

Пример использования:


$saw = new nokogiri($html);

var_dump($saw->get('a.')->toArray());

Ошибки страницы игнорируются. Парсер работает также с .class #id [attr=value]

Для простых страниц он неплох, однако код вида


<p>Hello <br> World</p>

он не распознает корректно, для этого придется вырезать <br> теги из страницы.

SimpleHTML

Адрес: http://simplehtmldom.sourceforge.net/

Очень медленный парсер. Работает по принципу jquery.


$shd = str_get_html($html);

foreach ($shd->find('div') as $div) {

echo $div->plaintext.'<br />';

}

Очень плохо относится к невалидным сайтам. Перед парсингом лучше пройтись Tidy. С моей задачей не справился и отвалился по переполнению памяти.

phpQuery

Адрес: http://phpquery-library.blogspot.com/

Довольно быстрый и удобный парсер. Свой выбор я остановил именно на нем.


$doc = phpQuery::newDocumentHTML($content);

phpQuery::selectDocument($doc);

// теперь мы можем обращаться к документу через функцию pq

foreach (pq('div.class') as $table) {
<p style="padding-left: 30px;">$pq = pq($table);</p>
<p style="padding-left: 30px;">// pq  это как $ в jQuery</p>
<p style="padding-left: 30px;">$date = $pq->find('time')->text();</p>
<p style="padding-left: 30px;">$imgsrc = $pq->find('a img')->attr('src');</p>
<p style="padding-left: 30px;">// также можно выполнять манипуляции с деревом</p>
<p style="padding-left: 30px;">$pq->find('header')->remove();
$pq->find('div')->remove();
$pq->find('a')->remove();
$pq->find('p')->not('.wysiwyg')->remove();</p>
<p style="padding-left: 30px;">$html =  $pq->html();</p>
}

Другая литература

  1. О Nokigiri на Хабре http://habrahabr.ru/post/110112/
  2. О phpQuery на Хабре http://habrahabr.ru/post/69149/
  3. Сравнение парсеров по скорости http://habrahabr.ru/post/114323/

Комментарии запрещены.