В настоящее время я пытаюсь (или планирую попытаться) написать простую (насколько это возможно) программу для синтаксического анализа HTML-документа в дерево.
После поиска в Google я нашел много ответов, в которых говорилось: «Не делай этого, это было сделано» (или слов в этом роде) и ссылок на примеры анализаторов HTML;а также довольно категоричная статья о том, почему не следует использовать регулярные выражения. Однако я не нашел руководств по "правильному" способу написания парсера. (Это, кстати, то, что я пытаюсь больше как учебное упражнение, чем что-либо еще, поэтому я бы предпочел сделать это, а не использовать готовый)
Я считаю, что мог бы создать рабочий XML-анализатор, просто чтение документа и добавление тегов / текста и т. д. к дереву, повышение уровня всякий раз, когда я нажимаю закрывающий тег (опять же, просто, на этом этапе не требуется никаких сложных потоков или эффективности). Однако для HTML не все теги закрыты.
Итак, у меня такой вопрос: что вы порекомендуете для решения этой проблемы? Единственная идея, которая у меня возникла, - это обрабатывать его так же, как XML, но иметь список тегов, которые не обязательно закрываются, каждый с условиями закрытия (например,
заканчивается
или следующийtag).
Есть ли у кого-нибудь другие (надеюсь, лучшие) предложения? Есть ли вообще лучший способ сделать это?
Итак, я постараюсь ответить здесь -
в основном, что отличает «простой» синтаксический анализ html (не говоря уже о действительном xhtml здесь) от разборов xml, это множество правил, таких как бесконечный 110] тэгов, или, строго говоря, тот факт, что даже самые небрежные из всех html-разметок будут несколько отрисовываться в браузере. Вам понадобится валидатор вместе с парсером, чтобы построить ваше дерево. Но вам нужно будет выбрать стандарт для HTML, который вы хотите поддерживать, так что, когда вы обнаружите слабость в разметке, вы поймете, что это ошибка, а не просто неаккуратный html.
Знайте все правила, создайте валидатор, и тогда вы сможете создать парсер. это план А.
План B должен предусматривать определенную устойчивость к ошибкам в вашем синтаксическом анализаторе, что сделает этап проверки ненужным. Например, проанализируйте все теги и поместите их в список, пропуская любые атрибуты, чтобы вы могли легко работать со списком, определяя, оставлен ли тег открытым или вообще никогда не открывался, чтобы в итоге получить «хороший» «Дерево макетов, которое будет приблизительным решением для небрежного макета, но при этом будет точным для правильного макета.
надеюсь, что это помогло!
Ослабление HTML может быть учтено путем определения недостающих тегов open и close по мере необходимости. По сути, это то, что делает валидатор типа Tidy.
Вы будете хранить стек (возможно, неявно с деревом) текущего контекста. Например, {<html>
, <body>
} означает, что вы в настоящее время находитесь в теле HTML-документа. Когда вы сталкиваетесь с новым узлом, вы сравниваете требования для этого узла с тем, что в данный момент находится в стеке.
Предположим, ваш стек на данный момент просто {html
}. Вы столкнулись с тегом <p>
. Вы смотрите <p>
в таблице, в которой говорится, что абзац должен быть внутри <body>
. Поскольку вы не в теле, вы неявно помещаете <body>
в свой стек (или добавляете узел тела в свое дерево). Затем вы можете положить <p>
в дерево.
Теперь предполагается, что вы видите другого <p>
. Ваши правила говорят вам, что вы не можете вкладывать абзац в абзац, поэтому вы должны вытолкнуть текущий <p>
из стека (как если бы вы видели закрывающий тег), прежде чем помещать новый абзац в стек.
В конце вашего документа вы вытаскиваете каждый оставшийся элемент из стека, как будто вы видели закрывающий тег для каждого из них.
Хитрость заключается в том, чтобы найти хороший способ представления требований к контексту для каждого элемента.
С тех пор как появился стандарт html5, написание html-парсера больше не является методом проб и ошибок или тайных знаний.
Вместо этого вам просто нужно реализовать стандартизированный алгоритм разбора .
Вы пытались использовать эту библиотеку: http://simplehtmldom.sourceforge.net/ ?
F.
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.