Написание HTML-парсера

В настоящее время я пытаюсь (или планирую попытаться) написать простую (насколько это возможно) программу для синтаксического анализа HTML-документа в дерево.

После поиска в Google я нашел много ответов, в которых говорилось: «Не делай этого, это было сделано» (или слов в этом роде) и ссылок на примеры анализаторов HTML;а также довольно категоричная статья о том, почему не следует использовать регулярные выражения. Однако я не нашел руководств по "правильному" способу написания парсера. (Это, кстати, то, что я пытаюсь больше как учебное упражнение, чем что-либо еще, поэтому я бы предпочел сделать это, а не использовать готовый)

Я считаю, что мог бы создать рабочий XML-анализатор, просто чтение документа и добавление тегов / текста и т. д. к дереву, повышение уровня всякий раз, когда я нажимаю закрывающий тег (опять же, просто, на этом этапе не требуется никаких сложных потоков или эффективности). Однако для HTML не все теги закрыты.

Итак, у меня такой вопрос: что вы порекомендуете для решения этой проблемы? Единственная идея, которая у меня возникла, - это обрабатывать его так же, как XML, но иметь список тегов, которые не обязательно закрываются, каждый с условиями закрытия (например,

заканчивается

или следующий

tag).

Есть ли у кого-нибудь другие (надеюсь, лучшие) предложения? Есть ли вообще лучший способ сделать это?

26
задан Einacio 25 August 2011 в 14:42
поделиться

5 ответов

Итак, я постараюсь ответить здесь -

в основном, что отличает «простой» синтаксический анализ html (не говоря уже о действительном xhtml здесь) от разборов xml, это множество правил, таких как бесконечный 110] тэгов, или, строго говоря, тот факт, что даже самые небрежные из всех html-разметок будут несколько отрисовываться в браузере. Вам понадобится валидатор вместе с парсером, чтобы построить ваше дерево. Но вам нужно будет выбрать стандарт для HTML, который вы хотите поддерживать, так что, когда вы обнаружите слабость в разметке, вы поймете, что это ошибка, а не просто неаккуратный html.

Знайте все правила, создайте валидатор, и тогда вы сможете создать парсер. это план А.

План B должен предусматривать определенную устойчивость к ошибкам в вашем синтаксическом анализаторе, что сделает этап проверки ненужным. Например, проанализируйте все теги и поместите их в список, пропуская любые атрибуты, чтобы вы могли легко работать со списком, определяя, оставлен ли тег открытым или вообще никогда не открывался, чтобы в итоге получить «хороший» «Дерево макетов, которое будет приблизительным решением для небрежного макета, но при этом будет точным для правильного макета.

надеюсь, что это помогло!

9
ответ дан 28 November 2019 в 07:39
поделиться

Ослабление HTML может быть учтено путем определения недостающих тегов open и close по мере необходимости. По сути, это то, что делает валидатор типа Tidy.

Вы будете хранить стек (возможно, неявно с деревом) текущего контекста. Например, {<html>, <body>} означает, что вы в настоящее время находитесь в теле HTML-документа. Когда вы сталкиваетесь с новым узлом, вы сравниваете требования для этого узла с тем, что в данный момент находится в стеке.

Предположим, ваш стек на данный момент просто {html}. Вы столкнулись с тегом <p>. Вы смотрите <p> в таблице, в которой говорится, что абзац должен быть внутри <body>. Поскольку вы не в теле, вы неявно помещаете <body> в свой стек (или добавляете узел тела в свое дерево). Затем вы можете положить <p> в дерево.

Теперь предполагается, что вы видите другого <p>. Ваши правила говорят вам, что вы не можете вкладывать абзац в абзац, поэтому вы должны вытолкнуть текущий <p> из стека (как если бы вы видели закрывающий тег), прежде чем помещать новый абзац в стек.

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

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

13
ответ дан 28 November 2019 в 07:39
поделиться

С тех пор как появился стандарт html5, написание html-парсера больше не является методом проб и ошибок или тайных знаний.

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

8
ответ дан 28 November 2019 в 07:39
поделиться

Вы пытались использовать эту библиотеку: http://simplehtmldom.sourceforge.net/ ?

F.

-1
ответ дан 28 November 2019 в 07:39
поделиться

Резкий. Перейти

HTML не является XML. XHTML - это XML. Большинство сайтов на HTML; некоторые из них XHTML. В XHTML все теги должны быть закрыты (или не иметь тела, которое все еще закрыто).

Если вы хотите написать HTML-парсер в качестве учебного эксперимента, тогда сделайте это. Если вы хотите написать следующий «Greaterest HTML parserer», тогда оставьте его. Apache (или кто-то еще) побеждает; важная информация: вы не знаете больше, чем большие группы, которые специализируются на разборе HTML.

Чтобы ответить на вопрос «Как с этим бороться?» Прочитайте спецификацию W3C по HTML . Это отвечает на ваш вопрос. Если ваш ответ «но я тоже не хочу», то вы на самом деле говорите: «Я ленивая тупица, которая хочет притворяться, что учится». Если это так, я предлагаю вам удалить пост и двигаться дальше; У команды Microsoft IE вероятно есть несколько документов, которые вас заинтересуют.

Менее резкий ответ

HTML не так просто разобрать. Как правило, вам не нужны элементы головы или тела, и многие теги не нужно закрывать. Основное правило при разборе HTML - , если вы встретите новый элемент блока, автоматически закройте предыдущий элемент блока . Вы не можете использовать стандартный синтаксический анализатор XML для этого, потому что HTML не является XML.

Как и в XML, вам нужно будет разбить ваш документ на элементы, включая текстовые элементы.

XHTML намного проще, потому что это должен быть правильно сформированный XML. Для этого вы можете использовать синтаксический анализатор XML.

5
ответ дан 28 November 2019 в 07:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: