Ехал я как-то с работы вместе со своим коллегой Валерой Щербининым и заговорили о теме парсинга HTML.
Большую часть времени на работе я занимаюсь поддержкой и активным развитием биллинговой подсистемы одной большой системы которая занимается записью компакт дисков. Название компании опускаю, так как я подписывал договор о неразглашении нечитая, посему не знаю что можно разглашать, а что нет :).
Учитывая специфику проекта и интеграцию всего со всем я трижды сталкивался с задачей импорта данных из HTML документов в биллинговую систему.
Три раза я использовал один и тот же подход - Regular Expression.
Причем один из документов имел такую нетривиальную структуру, что мне пришлось использовать аж два регулярных выражения. В один проход я выделял все данные вместе с частью HTML разметки, а во второй уже выкусывал сами данные. Мне пришлось так поступить, потому как я уважаю мэйнтейнеров и не хочу писать код, после которого меня будут долго вспоминать.
Кроме того, мне даже приходилось пережить один эпизод обновления разметки документа и обновлять свое же регулярные выражения...
Не могу пожаловаться на плохие знания языка регулярных выражений, но этот процесс доставлял мало удовольствия, был очень и очень медленным. Но самое главное - если код парсера хоть и был легко читаем и сопровождаем, то сами регулярные выражения были настоящей занозой в заднице.
Возможно Валера подумал что я полоумный, но тем не менее вежливо поделился своей идеей - использовать HTML Tidy для нормализации HTML до well formed XHTML, а потом наворачивать на это дело Xslt-преобразование которое извлекает все данные.
Идея мне сразу же понравилась. Но меня смутило то, что мне придется вызывать unmanaged HTML Tidy, плюс я практически незнаком с Xslt хотя и знаю XPath.
И вот, сегодня, совершенно случайно наткнулся на замечательное во всех отношениях решение - SGMLReader:
SGMLReader - Converting almost any HTML to valid XML
SGMLReader это pure C# .NET 2.0 библиотека, центральный класс которой это SgmlReader унаследованный от XmlReader со всем вытекающими отсюда преимуществами.
Есть даже примеры, которые запускаются на лету на живом коде из trunk:
HTML-to-XML Conversion Examples
Благодаря это библиотеке мне не придется погружаться в жестокий unmanaged мир и я смогу использовать Linq to Xml / Xslt / XPath на выбор.
В нагрузку ссылка на статью в которой описывается интеграция HTML Tidy и .NET. Если в двух словах то это либо P/Invoke либо COM Iterop. Брр...
Fix Up Your HTML with HTML Tidy and .NET
Ну и раз уж я удосужился написать пост, то упомяну что я завел себе твиттер :)
http://twitter.com/alexey_diyan
В твиттер я делаю посты очень часто. Всех интересующихся заверяю, что посты в твиттер буду делать только на техническую тематику.
Посты обычно касаются либо каких-то актуальных для меня вещей, изредка бывают 140-символьные размышлизмы.
воскресенье, 31 января 2010 г.
Подписаться на:
Комментарии к сообщению (Atom)
2 комментария:
Я обычно юзаю HtmlAgilityPack.. Он предоставляет XPathNavigable на лету. Удобно.
Миша, спасибо за наводку.
Когда потребуется у меня уже будет два варианта на рассмотрение.
Судя по всему HtmlAgilityPack более активно развивается в настоящее время.
Жалко что нет времени как следует посмотреть ни на первый ни на второй вариант :(
Отправить комментарий