我想使用PHPs解析HTML。我使用了xml_parser,但它不能像<img>
那样处理自动关闭标记。
例如,以下HTML代码段在到达结束标记</a>
:时会产生"不匹配的标记"错误
<a>
<img src="URL"><br>
</a>
很明显,原因是:xml_parser()不知道标记<img>
和<br>
不需要关闭(因为它们是自动关闭的)。
我知道我可以将HTML重写为<img src="URL"/><br/>
,以使解析器满意。然而,我希望解析器正确地处理这些HTML,因为上面的变体将是有效的HTML。
因此,我需要在onOpeningTag中告诉解析器这个标记是否自动关闭。这有可能吗?另一种选择是告诉解析器一个自关闭标记名称的列表。然而,我没有找到任何函数。因此,这个解析器也可能不支持"HTML"。
一个可接受的解决方案可能是完全禁用标记不匹配检查(或者自己实现HTML兼容版本)。
然而,PHP中可能存在一个我忽略的HTML特定版本。有什么建议我可以使用其他哪些简单的解析器实现吗?
到目前为止,我拥有的是:
<?php
// Command Line Parsing...
$file = $argv[1];
// Tag Handler functions
function onOpeningTag($parser, $name, $attrs) {
echo "OPEN: $name'n";
}
function onClosingTag($parser, $name) {
echo "CLOSE: $name'n";
}
function onContent($parser, $text) {
echo "TEXT (LEN:".strlen($text).")'n";
}
// Parser...
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "onOpeningTag", "onClosingTag");
xml_set_character_data_handler($xml_parser, "onContent");
if (!($fp = fopen($file, "r"))) die("Could not open file '$file'.'n");
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %d'n",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}
}
fclose($fp);
xml_parser_free($xml_parser);
?>
您想要用XML解析器解析HTML,这很容易引起问题。XML比HTML严格得多,您总是会遇到这样的问题。如果你的HTML不是像几十MB那样巨大,而是一个普通的网页,你可以只使用DOM-http://php.net/manual/en/book.dom.php.
$dom = new DOMDocument();
$dom->loadHtml($html);
$lists = $dom->getElementsByTagName('ul');
// bla bla bla
我的建议是尝试一个专门的HTML解析库。以下是一些提示:
- https://github.com/symfony/DomCrawler
- http://simplehtmldom.sourceforge.net/
- https://code.google.com/p/ganon/
愿原力与你同在!