如何使用Perl解析无效的HTML?

bod*_*ydo 6 html perl parsing html-parsing

我维护一个HTML格式的文章数据库.不幸的是,编写文章的编辑并不知道正确的HTML,所以他们经常写下这样的东西:

<div class="highlight"><html><head></head><body><p>Note that ...</p></html></div>
Run Code Online (Sandbox Code Playgroud)

我尝试使用HTML::TreeBuilder解析这个HTML,但在解析它并转储结果树之后,它们之间的所有元素<div class="highlight">...</div>都消失了.我只是离开了<div class="highlight"></div>.

编辑经常也做过这样的事情:

<div class="article"><style>@font-face {   font-family: "Cambria"; }</style>Article starts here</div>
Run Code Online (Sandbox Code Playgroud)

解析这个HTML::TreeBuilder结果<div class="article"></div>再次变为空.

任何想法如何处理这个破碎的HTML,并真正理解它?

Sin*_*nür 11

我会先通过HTML :: Tidy运行它:

#!/usr/bin/env perl

use strict; use warnings;
use HTML::Tidy;

my $html = <<EO_HTML;
<div class="highlight"><html><head></head>
<body><p>Note that ...</p></html>
</div>
EO_HTML

my $tidy = HTML::Tidy->new;

print $tidy->clean( $html );
Run Code Online (Sandbox Code Playgroud)

输出:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta name="generator" content="tidyp for Windows (v1.04), see www.w3.org">
<title></title>
</head>
<body>
<div class="highlight">
<p>Note that ...</p>
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

您可以通过设置各种配置选项来控制输出.

然后,通过解析器提供已清理的HTML.

否则,你可以尝试使用HTML :: TokeParser :: Simple或者甚至只是HTML :: Parser一次一步地构建一棵树,但我相信这种方式就是疯狂.

请记住,尝试构建树表示的解析器将比仅在识别它们时识别各种元素的流解析器更严格.