寻找可以清理错误HTML的PHP​​脚本

时间:2010-12-08 00:20:37

标签: php html-parsing

我正在编写一个PHP命令行脚本,使用Markdownify库将数百个HTML片段转换为Markdown。但是,我遇到过一些情况,我的某些HTML结构不够好,无法与Markdownify一起使用。所以我首先需要通过一些库来发送我的HTML,它可以清理它并添加可选的结束标记等。我将使用HTML的部分块,而不是完整的HTML文档,因此返回的HTML必须是部分的(和不包括doctype等。)

您知道可以将HTML转换为XHTML的PHP​​脚本吗?

解决方案:

利用PHP DOMDocument class。它会格式化您的HTML,即使它已被破坏。然后,您可以提取已清理的HTML:

libxml_use_internal_errors(true); //use this to prevent warning messages from displaying because of the bad HTML

$doc = new DOMDocument();
$doc->loadHTML($badHtml);
$goodHtml = $doc->saveHTML();

这将返回一个完整的HTML文档(在body标签中包含已清理的版本),即使我传递了HTML的部分块,因此我可以使用此正则表达式提取已清理的部分:

$goodHtmlPartial = trim(ereg_replace('(.*)<body>(.*)</body>(.*)', '\2', $goodHtml));

6 个答案:

答案 0 :(得分:8)

有什么理由不使用整洁?

http://php.net/manual/en/book.tidy.php

它可以清理你的html,只给你身体部分。

$tidy = tidy_repair_string($content,array(
                           'indent'         => true,
                           'output-html'   => true,
                           'wrap'           => 80,
                           'show-body-only' => true,
                           'clean' => true,
                           'input-encoding' => 'utf8',
                           'output-encoding' => 'utf8',
                           'logical-emphasis' => false,
                           'bare' => true,
                                          ));

答案 1 :(得分:5)

您可以将HTML加载到DOM,然后将save加载为XML。

答案 2 :(得分:4)

试试HTML Purifier;它非常适合清理糟糕的HTML,并且可以充当潜在恶意代码的过滤器。

答案 3 :(得分:2)

我建议您使用DOMDocument->loadHTML()方法。它会格式化您的HTML,即使它已被破坏。稍后,您可以将其另存为XML以获取XHTML。

答案 4 :(得分:0)

不是PHP,但是用于python的BeautifulSoup库有一些解析器,它们可以为几乎任何旧垃圾制作有效的html。

答案 5 :(得分:0)

                    libxml_use_internal_errors(true);

                    $dom = new \DOMDocument;
                    $dom->loadHTML($bad_html);

                    // Strip wrapping <html> and <body> tags
                    $mock = new \DOMDocument;
                    $body = $dom->getElementsByTagName('body')->item(0);
                    foreach ($body->childNodes as $child) {
                        $mock->appendChild($mock->importNode($child, true));
                    }

                    $fixed = trim($mock->saveHTML());
                    echo $fixed;