php simple html dom parser примеры

Учимся парсить сайты с библиотекой PHP Simple HTML DOM Parser

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

К примеру, из него нам нужно получить описание и url сайта. Если брать исключительно этот кусок кода, то все решается достаточно просто:

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

Такой код регулярному выражению не по зубам.

Обычно, в вузах на этот случай учат писать конечный автомат. Суть его в том, что мы перебираем, посимвольно, весь html текст, находим начало тега, и строим дерево документа. Так называемое DOM (Document Object Model)

Сейчас, писать такое самому нет необходимости.

В php, начиная с версии 5, есть встроенные методы работы с деревом документа (класс DOMDocument), но основан он на XML парсере.

А HTML и XML это хоть и очень похожие, но в тоже время абсолютно разные технологии.

К примеру, непременное требование к XML это закрытые теги и отсутствие ошибок.

Отсюда вытекает условие: ошибок в html, который мы парсим с помощью нативных средств php, быть не должно.

К сожалению, на сайтах донорах, ошибки не редки, а значит этот метод отпадает.

Некоторые из них, после небольших манипуляций скармливают 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 то вы просто передаете полученный текст этой функции.

Источник

Парсинг данных со страниц сайтов

Заметка о том, как собирать данные со страницы другого сайта с помощью библиотеки simple_html_dom.

Я уже касался темы поиска информации на страницы с помощью регулярных выражений и функций preg_match и preg_replace. Также разбирал как менять информацию на странице WordPress записи. Теперь разберём сбор информации сторонними инструментами, которые призваны упростить сбор данных.

simple_html_dom

Есть несколько библиотек упрощающих парсинг страниц. В данном примере мы будем использовать библиотеку simple_html_dom.php.

Скачиваем архив к себе на компьютер. Разархивируем его и файл simple_html_dom.php заливаем на свой сервер.

Теперь подключаем этот файл:

^^ путь приведен для тем сайтов на WordPress.

Перед работой, в самом файле simple_html_dom.php надо закомментировать строчку:

Вместо неё поставить:

Это делается, чтобы избежать ошибок, которые могут появляться:

Notice: Undefined offset: 0 in /wp-content/themes/ploshadka.net/parser-page.php on line 89

Notice: Trying to get property of non-object in /wp-content/themes/ploshadka.net/parser-page.php on line 89

php — Fatal error: Call to a member function find() on a non-object …

Uncaught Error: Call to a member function findfind() on string in

В этой статье я не буду касаться того как скачать файл с другого сайта к себе на сервер. Но лучше парсить страницы, предварительно скачав их себе.

Пример нахождения html тега td с классом person.

// Очищаем вывод, чтобы не засорялся буфер обмена
$html->clear();
unset($html);
>
?>

Основные моменты в коде выше я сопроводил пояснениями.

С помощью этого php мы нашли информацию находящуюся в теге:

Примеры поиска и вывода данных

Найдёт html тег div с >

Выведет все текстовые значения внутри ссылки:

Сохранит найденное в переменную, массив данных из которой потом можно вывести отдельно:

Отдельные части опять же можно сохранить в переменную:

Источник

Парсинг от А до Я

Блог о программировании парсеров и web-автоматизации

Поиск по блогу

четверг, 20 мая 2010 г.

PHP Simple HTML DOM Parser

A simple PHP HTML DOM parser written in PHP5+, supports invalid HTML, and provides a very easy way to handle HTML elements.

Еще в числе плюсов, которые я отметила, — отсутствие проблем с кодировками. Часто бывает, что, получив содержимое страницы с помощью, например, file_get_contents, кодировку данных на промежуточном этапе приходится преобразовывать. Здесь же такой надобности у меня пока что не возникало.

С помощью этой библиотеки вы можете обращаться к элементам и атрибутам элементов, искать определенного уровня вложенные элементы, фильтровать их, искать текст и комментарии(!).

Приведу примеры из документации:

Вот так будет выглядеть код с использованием Simple HTML DOM Parser :

А вот код с использованием domDocument :

Зато я визуально смогла оценить работу библиотеки Simple HTML DOM Parser с «невалидным» html. Если перед строкой

не поставить «@», то при работе скрипта с domDocument вывалится куча варнингов типа:

Warning: DOMDocument::loadHTML() [function.DOMDocument-loadHTML]: Tag nobr invalid in Entity, line: 5
Warning: DOMDocument::loadHTML() [function.DOMDocument-loadHTML]: htmlParseEntityRef: expecting ‘;’ in Entity, line: 5

Кроме того видна разница и в выводе результатов (кодировка):
php simple html dom parser примеры. Смотреть фото php simple html dom parser примеры. Смотреть картинку php simple html dom parser примеры. Картинка про php simple html dom parser примеры. Фото php simple html dom parser примеры
php simple html dom parser примеры. Смотреть фото php simple html dom parser примеры. Смотреть картинку php simple html dom parser примеры. Картинка про php simple html dom parser примеры. Фото php simple html dom parser примеры

В общем, библиотека мне нравится, кто еще не пользовался — советую попробовать.

Чтобы быть в курсе обновлений блога, можно подписаться на RSS.

Источник

Недостатки simple_html_dom или парсинг сложных страниц

Я уже писал о библиотеке simple_html_dom, с помощью которой можно парсить страницы сайтов. В этой заметке поделюсь некоторыми наработками, когда содержимое имеет одинаковые контейнеры.

Что делать когда сложно зацепиться за DOM элементы?

По неизвестной мне причине в библиотеке simple_html_dom не работает несколько классов в html элементе. Например, не получится найти и сделать выборку по строке:

Очевидным будет использовать конструкции вроде:

но на деле это не работает или почти никогда не работает.

Описание задачи

Нужно найти два отдельных блока содержимого. Оба блока имеют одинаковые свойства и потому не цепляются по отдельности.

Сначала preg_match потом simple_html_dom

Для этих целей можно было бы использовать сначала конструкции preg_match, чтобы найти определённое содержимое страницы:

Код выше схватит всё что начинается с «Первого заголовка» и до «второго заголовка».

Иногда приходится так изощрять код, потому что иначе не захватить точный кусок кода. В базовых примерах php часто даются простые и типовые ситуации, которые не работают в сложных случаях.

А вот ещё один код:

С помощью него мы уже захватим всё что после второго заголовка.

А потом уже из найденного использовать выборку

Но здесь возникает другая проблема. Содержимое в переменной matches отказывается пониматься и выводит разного рода ошибки. Даже, если содержимое конвертировать в массивы или строки, всё равно чего-то не хватает. А что именно, совсем не ясно.

Хотя в обратную сторону работает. Если сначала сделать выборку через simple_html_dom, то потом можно вполне забирать информацию через preg_match.

В ином случае остаётся придерживаться одного стиля, либо использовать только preg_match либо simple_html_dom. В данной статье будем использовать только второе.

if ( file_exists($file_temp) ) <
$html = file_get_html($file_temp); // Используем библиотеку
>

Только simple_html_dom

Если перед парсингом нужно удалить какие-то данные, воспользуйтесь этой статьёй.

В коде уже привел все пояснения. Первый блок находим так.

// На всякий случай избавимся от лишних пробелов с обоих сторон найденного
$one = trim($one);
$two = trim($two);
$three = trim($three);

// Дальше можно поменять содержимое одного найденного объекта
$three = preg_replace(‘/\/\//’,’https://’,$three); // меняем в начале ссылку ‘//’ на ‘https://’

И так 5 строк в массиве. Дальше с этим массив можно делать всё что угодно.

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

Предположим что первый блок меняется и содержит всегда разное количество информации. И не получится это обойти используя наш первый массив, начиная например с 6-ого значения: our_array[5]. Ведь в другой раз, на другой странице, нужные нам данные могут начинаться с третьей позиции или любой другой.

Мы знаем, что второй блок, к счастью начинается сразу за первым. Или любым другим, но идёт всегда в одинаковом порядке. В приведенном примере всегда после первого блока. Тогда добавляем следующую конструкцию:

Здесь всё тоже самое, что и в первом блоке.

Как видно, содержимое второго php блока повторяет первый, за исключением того, что мы находим первый блок и пропускаем его с помощью конструкции if($i==1) continue. И обязательно останавливаем наш поиск на втором блоке. Иначе схватится лишнее. Одинаковых контейнеров может быть очень много.

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

Кстати, на сайте нет рекламы. У сайта нет цели самоокупаться, но если вам пригодилась информация можете задонатить мне на чашечку кофе в макдаке. Лайкнуть страницу или просто поблагодарить. Карма вам зачтется.

Источник

PHP Simple HTML DOM Parser – библиотека для парсинга сайтов

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

К примеру, из него нам нужно получить описание и url сайта. Если брать исключительно этот кусок кода, то все решается достаточно просто:

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

Такой код регулярному выражению не по зубам.

Обычно, в вузах на этот случай учат писать конечный автомат. Суть его в том, что мы перебираем, посимвольно, весь html текст, находим начало тега, и строим дерево документа. Так называемое DOM (Document Object Model)

Сейчас, писать такое самому нет необходимости.

В php, начиная с версии 5, есть встроенные методы работы с деревом документа (класс DOMDocument), но основан он на XML парсере.

А HTML и XML это хоть и очень похожие, но в тоже время абсолютно разные технологии.

К примеру, непременное требование к XML это закрытые теги и отсутствие ошибок.

Отсюда вытекает условие: ошибок в html, который мы парсим с помощью нативных средств php, быть не должно.

К сожалению, на сайтах донорах, ошибки не редки, а значит этот метод отпадает.

Некоторые из них, после небольших манипуляций скармливают html тому же DOMDocument. Мы не будем их рассматривать.

В этой статье я расскажу про SimpleHTMLDOM. Этой библиотекой я пользуюсь уже несколько лет, и она меня еще ни разу не подводила.

Скачиваем последнюю версию здесь.

Пусть Вас не смущает то, что она не обновлялась с 2008 года, то, что она умеет, полностью покроет Ваши нужды в разборе html текстов.

В архиве, который вы скачали, две папки (примеры работы и документация) и файл simple_html_dom.php.

simple_html_dom.php это и есть вся библиотека, больше ничего для работы не потребуется. Кидаем этот файл в папку с проектом и в своем скрипте просто подгружаем его.

Кроме документации, которую вы скачали с архивом, доступна еще online версия, ее вы найдете здесь

Файл подключен и готов к работе.

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

В simplehtmldom есть методы для удаленной загрузки страниц. После подключения файла библиотеки, нам доступны 2 функции для обработки HTML строк.

str_get_html(str) и file_get_html(url)

Они делают одно и тоже, преобразуют HTML текст в DOM дерево, различаются лишь источники.

str_get_html – на вход получает обычную строку, т.е. если вы получили HTML прибегнув к curl, или file_get_contents то вы просто передаете полученный текст этой функции.

file_get_html – сама умеет загружать данные с удаленного URL или из локального файла

К сожалению, file_get_html загружает страницы обычным file_get_contents. Это значит если хостер, выставил в php.ini allow_url_fopen = false (т.е. запретил удаленно открывать файлы), то загрузить что-то удаленно, не получится. Да и серьезные веб сайты таким способом парсить не стоит, лучше использовать CURL с поддержкой proxy и ssl. Однако для наших опытов, вполне хватит и file_get_html.

При больших объемах данных, в библиотеке происходит утечка памяти. Поэтому после окончания одного цикла надо ее чистить.

Делает это метод clear.

К примеру грузим 5 раз сайт www.yandex.ru с разными поисковыми запросами

После того, как html текст упакован в объект, можно приступать непосредственно к поиску нужных элементов.

Большинство поисковых функций выполняет метод find(selector, [index]). Если второй аргумент не задан, метод возвращает массив элементов. Если же задан то элемент этого массива с индексом index.

Пример: скачаем главную страницу моего блога, и выведем все ссылки, которые встретим на своем пути.

Поиск по названию тега вы уже видели

или комбинированный вариант

в данном случае, сначала найдется элемент с затем в нем найдутся все теги div, и уже среди них фильтруются те у которых >

Если метод find ничего не нашел и index не задан, то он возвращает пустой массив. Если же index задан, то метод возвращает null.

Поэтому верным решением будет проверить

Поиск по наличию атрибута

или более конкретный поиск по значению атрибута

Такая нотация позволяет искать по двум и более смежным классам

Поиск нескольких тегов

Поиск вложенных тегов

У каждого найденного элемента также есть метод

если нам нужно найти все li только первого div’а то мы можем написать так

Поиск по значению атрибута не ограничивается только равенством. Вот доступные условия

[атрибут] – проверяет есть ли у элемента данный атрибут

[атрибут=величина] – проверяет, есть ли у элемента данный атрибут и равно ли его значение величине.( div[class=myclass] – найдет все div’ы у которых class равен myclass)

[атрибут!=величина] – проверяет, есть ли у элемента данный атрибут и не равно ли его значение величине.( div[class!=myclassok] – найдет все div’ы у которых class не равен myclassok)

[атрибут^=величина] – проверяет, есть ли у элемента данный атрибут и начинается ли его значение с величины ( div[class^=my] – найдет все div’ы у которых class начинается с my, к примеру myclass и myclassok)

[атрибут$=величина] – проверяет, есть ли у элемента данный атрибут и заканчивается ли его значение величиной( div[class$=ok] – найдет все div’ы у которых class заканчивается на ok, к примеру myclassok, yok, okно не oki)

[атрибут*=величина] – проверяет, есть ли у элемента данный атрибут и содержит ли его значение в себе величину, в любом месте(div[class*=sok] – найдет все div’ы у которых class содержит sok, к примеру myclassok, ysoki, sok)

Обычный текст можно искать как тег text

Комментарии находим по тегу comment1

$e->tag Читает или записывает имя тега элемента.

$e->outertext Читает или записывает весь HTML элемента, включая его самого.

$e->innertext Читает или записывает внутренний HTML элемента

$e->plaintext Читает или записывает простой текст элемента, это эквивалентно функции strip_tags($e->innertext). Хотя поле доступно для записи, запись в него ничего не даст, и исходный html не изменит

Как Вы могли догадаться, для удаления ненужного элемента из HTML можно затереть его поле outertext

Тут следует помнить, что хоть элемент и не виден в html, из дерева DOM он никуда не делся

при желании мы даже можем вернуть элемент на место

Для более эффективной навигации по дереву документа доступны методы

$e->parent() Возвращает родительский элемент.

$e->first_child() Возвращает первый дочерний элемент, или null, если ничего не найдено

$e->last_child() Возвращает последний дочерний элемент, или null, если ничего не найдено

$e->next_sibling() Возвращает следующий родственный элемент, или null, если ничего не найдено

$e->prev_sibling() Возвращает предыдущий родственный элемент, или null, если ничего не найдено

Все дочерние элементы разные, как-то подобрать к ним селектор проблематично. Поэтому воспользуемся описанными методами.

Данные методы полезны при разборе таблиц, элементы которых, как правило, структурированы, но не имеют идентифицирующих атрибутов.

Ну и последняя фишка это вызов callback функции на найденный элемент

На экране мы увидим

Доступ к атрибутам элементов осуществляется напрямую

Хватит теории, перейдем к практике

Загрузим n фотографий из поисковой выдачи Yandex Картинок. http://images.yandex.ru/

Как быть если нам нужно больше фото, чем лежит на одной странице?

Ответ прост: Код, приведенный выше, заключается в функцию, в html помимо фото находим еще и URLвсех страниц, и рекурсивно вызываем данную функцию для этих страниц.

Все хорошо, 200 картинок лежат в папке data. Но их размер слишком мал.

Поэтому завершающим аккордом нашей практики будет загрузка увеличенной фотографии.

Для этого определим еще одну функцию

и слегка поправим getYandexImages

Вот и все, наслаждаемся фото великолепной Джессики Альбы. Надеюсь меня простит Яндекс, ведь по сути фото грабится не с их серверов, а с прямиком с сайтов, где они лежат.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *