Учимся парсить сайты с библиотекой PHP Simple HTML DOM Parser
Те, кто хоть раз писал парсер, знает, что не стоит этого делать с помощью регулярных выражений. Проиллюстрировать это утверждение поможет следующий пример.
К примеру, из него нам нужно получить описание и url сайта. Если брать исключительно этот кусок кода, то все решается достаточно просто:
echo ‘url:’ . $list [1]. ‘,title:’ . $list [2]. $list [3]; // выведет url:http://xdan.ru,title:Сайт по программированию парсеров и многое другое
Проблемы начинаются тогда, когда описание сайта заполняют пользователи, и оно не имеет определенного шаблона.
Такой код регулярному выражению не по зубам.
Обычно, в вузах на этот случай учат писать конечный автомат. Суть его в том, что мы перебираем, посимвольно, весь html текст, находим начало тега, и строим дерево документа. Так называемое DOM (Document Object Model)
Сейчас, писать такое самому нет необходимости.
В php, начиная с версии 5, есть встроенные методы работы с деревом документа (класс DOMDocument), но основан он на XML парсере.
А HTML и XML это хоть и очень похожие, но в тоже время абсолютно разные технологии.
К примеру, непременное требование к XML это закрытые теги и отсутствие ошибок.
Отсюда вытекает условие: ошибок в html, который мы парсим с помощью нативных средств php, быть не должно.
К сожалению, на сайтах донорах, ошибки не редки, а значит этот метод отпадает.
Для корректного разбора таких сайтов, на помощь придут php библиотеки PHPQuery, Simple HTML DOM, Zend DOM Query, Nokogiri .
Некоторые из них, после небольших манипуляций скармливают html тому же DOMDocument. Мы не будем их рассматривать.
В этой статье я расскажу про SimpleHTMLDOM. Этой библиотекой я пользуюсь уже несколько лет, и она меня еще ни разу не подводила.
Скачиваем последнюю версию здесь.
Пусть Вас не смущает то, что она не обновлялась с 2008 года, то, что она умеет, полностью покроет Ваши нужды в разборе html текстов.
В архиве, который вы скачали, две папки (примеры работы и документация) и файл simple_html_dom.php.
simple_html_dom.php это и есть вся библиотека, больше ничего для работы не потребуется. Кидаем этот файл в папку с проектом и в своем скрипте просто подгружаем его.
Кроме документации, которую вы скачали с архивом, доступна еще online версия, ее вы найдете здесь
Файл подключен и готов к работе.
Для того, чтобы начать разбирать HTML, его сперва нужно получить. Обычно, я делаю это при помощи библиотеки CURL.
В simplehtmldom есть методы для удаленной загрузки страниц. После подключения файла библиотеки, нам доступны 2 функции для обработки HTML строк.
str_get_htm(str) и file_get_html(url)
Они делают одно и тоже, преобразуют HTML текст в DOM дерево, различаются лишь источники.
str_get_htm – на вход получает обычную строку, т.е. если вы получили HTML прибегнув к curl, или file_get_contents то вы просто передаете полученный текст этой функции.
file_get_html – сама умеет загружать данные с удаленного URL или из локального файла
PHP HTML DOM парсер с jQuery подобными селекторами
Добрый день, уважаемые хабровчане. В данном посте речь пойдет о совместном проекте S. C. Chen и John Schlick под названием PHP Simple HTML DOM Parser (ссылки на sourceforge).
Идея проекта — создать инструмент позволяющий работать с html кодом используя jQuery подобные селекторы. Оригинальная идея принадлежит Jose Solorzano’s и реализована для php четвертой версии. Данный же проект является более усовершенствованной версией базирующейся на php5+.
В обзоре будут представлены краткие выдержки из официального мануала, а также пример реализации парсера для twitter. Справедливости ради, следует указать, что похожий пост уже присутствует на habrahabr, но на мой взгляд, содержит слишком малое количество информации. Кого заинтересовала данная тема, добро пожаловать под кат.
Получение html кода страницы
$html = file_get_html('http://habrahabr.ru/'); //работает и с https://
Товарищ Fedcomp дал полезный комментарий насчет file_get_contents и 404 ответа. Оригинальный скрипт при запросе к 404 странице не возвращает ничего. Чтобы исправить ситуацию, я добавил проверку на get_headers. Доработанный скрипт можно взять тут.
Поиск элемента по имени тега
foreach($html->find('img') as $element) < //выборка всех тегов img на странице echo $element->src . '
'; // построчный вывод содержания всех найденных атрибутов src >
Модификация html элементов
$html = str_get_html('HelloWorld'); // читаем html код из строки (file_get_html() - из файла) $html->find('div', 1)->class = 'bar'; // присвоить элементу div с порядковым номером 1 класс "bar" $html->find('div[id=hello]', 0)->innertext = 'foo'; // записать в элемент div с текст foo echo $html; // выведет fooWorld
Получение текстового содержания элемента (plaintext)
echo file_get_html('http://habrahabr.ru/')->plaintext;
Целью статьи не является предоставить исчерпывающую документацию по данному скрипту, подробное описание всех возможностей вы можете найти в официальном мануале, если у сообщества возникнет желание, я с удовольствием переведу весь мануал на русский язык, пока же приведу обещанный в начале статьи пример парсера для twitter.
Пример парсера сообщений из twitter
require_once 'simple_html_dom.php'; // библиотека для парсинга $username = 'habrahabr'; // Имя в twitter $maxpost = '5'; // к-во постов $html = file_get_html('https://twitter.com/' . $username); $i = '0'; foreach ($html->find('li.expanding-stream-item') as $article) < //выбираем все li сообщений $item['text'] = $article->find('p.js-tweet-text', 0)->innertext; // парсим текст сообщения в html формате $item['time'] = $article->find('small.time', 0)->innertext; // парсим время в html формате $articles[] = $item; // пишем в массив $i++; if ($i == $maxpost) break; // прерывание цикла >
Вывод сообщений
for ($j = 0; $j < $maxpost; $j++) < echo ''; echo '' . $articles[$j]['text'] . '
'; echo '' . $articles[$j]['time'] . '
'; echo ''; >
Благодарю за внимание. Надеюсь, получилось не очень тяжеловесно и легко для восприятия.
Похожие библиотеки
P.S.
Хаброжитель Groove подсказал что подобные материалы уже были
P.P.S.
Постараюсь в свободное время собрать все библиотеки и составить сводные данные по производительности и приятности использования.
Quick Start
Find below sample code that demonstrate the fundamental features of PHP Simple HTML DOM Parser.
Read plain text from HTML document
echo file_get_html('https://www.google.com/')->plaintext;
Loads the specified HTML document into memory, parses it and returns the plain text. Note that file_get_html supports local files as well as remote files!
Read plaint text from HTML string
Parses the provided HTML string and returns the plain text. Note that the parser handles partial documents as well as full documents.
Read specific elements from HTML document
$html = file_get_html('https://www.google.com/'); foreach($html->find('img') as $element) echo $element->src . '
'; foreach($html->find('a') as $element) echo $element->href . '
';
Loads the specified document into memory and returns a list of image sources as well as anchor links. Note that find supports CSS selectors to find elements in the DOM.
Modify HTML documents
$doc = ' find('div', 1)->class = 'bar'; $html->find('div[id=hello]', 0)->innertext = 'foo'; echo $html; // Parses the provided HTML string and replaces elements in the DOM before returning the updated HTML string. In this example, the class for the second div element is set to bar and the inner text for the first div element to foo .
Note that find supports a second parameter to return a single element from the array of matches.
Note that attributes can be accessed directly by the means of magic methods ( ->class and ->innertext in the example above).
Collect information from Slashdot
$html = file_get_html('https://slashdot.org/'); $articles = $html->find('article[data-fhtype="story"]'); foreach($articles as $article) < $item['title'] = $article->find('.story-title', 0)->plaintext; $item['intro'] = $article->find('.p', 0)->plaintext; $item['details'] = $article->find('.details', 0)->plaintext; $items[] = $item; > print_r($items);
Collects information from Slashdot for further processing.
Note that the combination of CSS selectors and magic methods make the process of parsing HTML documents a simple task that is easy to understand.