Как стать автором
Обновить

Комментарии 15

Действительно, без DOM дерева толку от него мало. Такой токенизер ничем не лучше простого regex
Хотя я не прав. В задачи токенизера и не входит составление дерева.
И часто лучше всего парсить регэкспом.
Поясню:
Участвовал в нескольких проектах где нужно было парсить html и выцеплять оттуда данные.
Я подготовил код для парсинга более 200 сайтов (на каждом несколько типов страниц).
Так же я работал в команде, решение чам парсить и как парсить принимал не я.

В коде были методы для парсинга и через XPath и движёк основанный на Regexp, так вот регэкспы гораздо быстрее проще и надежнее написать.

Проблемы, что один и тот же тэг может быть по разному записан, атрибуты поменены местами, используются разные кавычки итд, здесь практически нет. На самом деле на практике на одной и той же странице и в одном и том же месте тег всегда, ВСЕГДА, одинаковый.

С Xpath же проблема что выражение типа
"/html/body/div[6]/div[2]/div/div[7]/div/div[3]/div/div[2]/div/ol/li[2]/div/h3/a" (то что выдаёт firebug) совершенно не надёжно.

Искать же каждый элементы по именам классов, id и т.д. сложнее и дольше чем писать регэкспы,
так как бывает что ни стилей ни id у них нет, бывает что тэгов в иерархии много и в каждом используется несколько (3-4) классов, бывает что xpath не хватает и нужно написать какойто код который по обходить dom.

Надёжностью это решение тоже не отличается.

Ещё был проект гду нужно было писать интеграционные тесты для legacy rails приложения перед рефакторингом, (именно интеграционные тестирующие полностью весь стек, без mock). Там мы парсили DOM для валидации того что есть на странице. Где-то в 30% случаев гораздо проще было парсить регэкспом (хотя бы частично).
Не советую использовать XPath скопированный из Firebug.
Поясню — если скопировать XPath к заголовку статьи на хабре, то получим /html/body/div/div[2]/div[3]/div/div[2]/h1/a, который поломается с большой вероятностью при изменении дизайна.
Если же немножко подумать головой, то можно написать //h3[@ class='title']/a[@ class='post_title'] или вообще ограничиться //a[@ class='post_title']. И такой XPath будет понадежнее любой регулярки.

Опять же, в своих проектах держу несколько функций-расширений XPath, например has-class(), has-classes(), url-path-regexp(), url-domain() и пр (по названию думаю понятно что они делают).
Про это всё я написал.
Да, Моджо после ТокеПарсера выглядит фантастическим.
Единственное, что на некоторых виртуальных хостингах нет нужной для Моджо версии перла и это создаёт ряд неудобств с внедрением нового в древние проекты.
Есть еще HTML::DOM
1. Не стоит пользоваться хостингами с древней версией перла.
2. Есть форк Mojo который работает с perl 5.8.8
также в комплекте модуль ojo для подобных однострочников:

perl -Mojo -E 'say g("mojolicio.us")->dom->at("title")->text'
А вот такой абсолютно валидный HTML представим в виде DOM?

<b><i>xxx</b></i>
Валидный по чьему мнению? :) Валидатор W3C не считает его валидным: «end tag for element „I“ which is not open».
Расширение DOM php кидает warning'и на ту же тему, но распарсивает нормально, на выходе получается корректный html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><b><i>xxx</i></b></body></html>

Что получится конкретно с Mojo::DOM в Perl не знаю, но думаю все будет аналогично.
Валидный с точки зрения отображения в браузере.
Если браузет такое отображает (а многие, если не все — отображают без проблем), то значит есть сайты на которых такое встречается.
И значит ваш парсер должен быть готов к этому.
Еще есть Web::Query, HTML::Parser и т.д. Пример написан для HTML::TokeParser, использование которого, все же можно часто встретить, например, в англоязычной литературе по Perl, кроме того, он включен в Perl из коробки. Именно с этого модуля, автором которого является Gisle Aas, сделавший еще целую кучу полезных модулей, многие начинали на Perl.

А, например, подход Microsoft, который заключался в том, что используя OLE::Automation и IE можно получать доступ к DOM и делать все что угодно, плюс выполнение JavaScript и т.д., еще круче чем Mojo::DOM, но значит ли это, что все Perl Win32 программисты побегут юзать IE?

Использовать регулярные выражения в парсинге HTML — это конечно же красный сигнал, для тех кто минусует. Вот пример, на stackoverflow.com — один человек попросил написать регулярное выражение для парсинга куска HTML, другой это сделал, его сразу же заминусовали, мне интересно люди хоть прочитали, что изначально спрашивал человек. Еще мне интересно, если тому кто усиленно минусует регулярные выражения, скажут, друг, я тебя заплачу намного больше, если ты вместо высоуровневего ООП модного модуля, просто будешь использовать регулярные выражения, он что откажется? ;)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации