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


当前回答

我们以前已经为我们的需求创建了不少爬虫。最后,通常是简单的正则表达式做得最好。虽然上面列出的库对于创建它们的原因来说是很好的,但如果您知道自己在寻找什么,正则表达式是一种更安全的方法,因为您还可以处理无效的HTML/XTML结构,如果通过大多数解析器加载,则会失败。

其他回答

如果您熟悉jQuery选择器,可以使用ScarletsQuery for PHP

<pre><?php
include "ScarletsQuery.php";

// Load the HTML content and parse it
$html = file_get_contents('https://www.lipsum.com');
$dom = Scarlets\Library\MarkupLanguage::parseText($html);

// Select meta tag on the HTML header
$description = $dom->selector('head meta[name="description"]')[0];

// Get 'content' attribute value from meta tag
print_r($description->attr('content'));

$description = $dom->selector('#Content p');

// Get element array
print_r($description->view);

这个库通常需要不到1秒的时间来处理脱机html。它还接受无效的HTML或标记属性上缺少引号。

顺便说一下,这通常被称为屏幕刮擦。我为此使用的库是SimpleHTMLDomParser。

您可以尝试使用类似HTMLTidy的东西来清理任何“损坏”的HTML,并将HTML转换为XHTML,然后可以使用XML解析器解析。

简单HTML DOM是一个很棒的开源解析器:

simplehtmldom.sourceforge

它以面向对象的方式处理DOM元素,新的迭代包含了大量不兼容代码。还有一些很棒的函数,如JavaScript中的“find”函数,它将返回该标记名元素的所有实例。

我已经在许多工具中使用了这个,在许多不同类型的网页上测试了它,我认为它非常有用。

注意,这个答案推荐了那些已经废弃了10多年的图书馆。

phpQuery和QueryPath在复制流畅的jQuery API方面非常相似。这也是为什么它们是在PHP中正确解析HTML的两种最简单的方法。

QueryPath示例

基本上,您首先从HTML字符串创建一个可查询的DOM树:

 $qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL

结果对象包含HTML文档的完整树表示。可以使用DOM方法遍历它。但常见的方法是使用jQuery中的CSS选择器:

 $qp->find("div.classname")->children()->...;

 foreach ($qp->find("p img") as $img) {
     print qp($img)->attr("src");
 }

大多数情况下,您希望为->find()使用简单的#id和.class或DIV标记选择器。但您也可以使用XPath语句,这有时会更快。另外,典型的jQuery方法,如->children()和->text(),特别是->attr(),简化了提取正确的HTML片段。(并且已经解码了它们的SGML实体。)

 $qp->xpath("//div/p[1]");  // get first paragraph in a div

QueryPath还允许将新标记注入流(->追加),然后输出并美化更新的文档(->写入HTML)。它不仅可以解析格式错误的HTML,还可以解析各种XML方言(带有名称空间),甚至可以从HTML微格式(XFN、vCard)中提取数据。

 $qp->find("a[target=_blank]")->toggleClass("usability-blunder");

.

phpQuery还是QueryPath?

一般来说,QueryPath更适合处理文档。而phpQuery还实现了一些伪AJAX方法(仅HTTP请求),以更接近于jQuery。据称,phpQuery通常比QueryPath更快(因为总体特性较少)。

有关差异的更多信息,请参阅tagbyte.org上的wayback机器上的比较

优势

简单可靠易于使用的替代方案->查找(“a img,a object,div a”)正确的数据取消捕获(与正则表达式grepping相比)