如何解析HTML/XML并从中提取信息?


当前回答

不使用正则表达式解析HTML有几个原因。但是,如果您完全控制将生成什么HTML,那么可以使用简单的正则表达式。

上面是一个通过正则表达式解析HTML的函数。请注意,此函数非常敏感,要求HTML遵守某些规则,但它在许多场景中都非常有效。如果您想要一个简单的解析器,并且不想安装库,请尝试一下:

function array_combine_($keys, $values) {
    $result = array();
    foreach ($keys as $i => $k) {
        $result[$k][] = $values[$i];
    }
    array_walk($result, create_function('&$v', '$v = (count($v) == 1)? array_pop($v): $v;'));

    return $result;
}

function extract_data($str) {
    return (is_array($str))
        ? array_map('extract_data', $str)
        : ((!preg_match_all('#<([A-Za-z0-9_]*)[^>]*>(.*?)</\1>#s', $str, $matches))
            ? $str
            : array_map(('extract_data'), array_combine_($matches[1], $matches[2])));
}

print_r(extract_data(file_get_contents("http://www.google.com/")));

其他回答

这听起来像是W3C XPath技术的一个很好的任务描述。很容易表达诸如“返回嵌套在<foo><bar><baz>元素中的img标记中的所有href属性”之类的查询。我不是一个PHP爱好者,无法告诉您XPath可能以什么形式可用。如果可以调用外部程序来处理HTML文件,则应该能够使用命令行版本的XPath。有关快速介绍,请参见http://en.wikipedia.org/wiki/XPath.

Advanced Html Dom是一个简单的Html Dom替代品,它提供了相同的界面,但它是基于Dom的,这意味着不会出现任何相关的内存问题。

它还具有完整的CSS支持,包括jQuery扩展。

您可以尝试的另一个选项是QueryPath。它的灵感来自jQuery,但在服务器上使用PHP,并在Drupal中使用。

使用FluidXML,您可以使用XPath和CSS选择器查询和迭代XML。

$doc = fluidxml('<html>...</html>');

$title = $doc->query('//head/title')[0]->nodeValue;

$doc->query('//body/p', 'div.active', '#bgId')
        ->each(function($i, $node) {
            // $node is a DOMNode.
            $tag   = $node->nodeName;
            $text  = $node->nodeValue;
            $class = $node->getAttribute('class');
        });

https://github.com/servo-php/fluidxml

我在这里没有提到的一种通用方法是通过Tidy运行HTML,它可以设置为输出保证有效的XHTML。然后可以在上面使用任何旧的XML库。

但对于您的具体问题,您应该看看这个项目:http://fivefilters.org/content-only/--这是Readability算法的一个修改版本,它旨在从页面中提取文本内容(而不是页眉和页脚)。