如何解析HTML/XML并从中提取信息?
当前回答
对于1a和2:我将投票支持新的Symfony Componet类DOMCrawler(DOMCrawler)。此类允许类似于CSS选择器的查询。看看这个演示文稿,看看真实世界的例子:news-of-the-symfony2-world。
该组件设计为独立工作,可以在没有Symfony的情况下使用。
唯一的缺点是它只适用于PHP5.3或更高版本。
其他回答
我们以前已经为我们的需求创建了不少爬虫。最后,通常是简单的正则表达式做得最好。虽然上面列出的库对于创建它们的原因来说是很好的,但如果您知道自己在寻找什么,正则表达式是一种更安全的方法,因为您还可以处理无效的HTML/XTML结构,如果通过大多数解析器加载,则会失败。
使用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
注意,这个答案推荐了那些已经废弃了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相比)
您可以尝试的另一个选项是QueryPath。它的灵感来自jQuery,但在服务器上使用PHP,并在Drupal中使用。
我在这里没有提到的一种通用方法是通过Tidy运行HTML,它可以设置为输出保证有效的XHTML。然后可以在上面使用任何旧的XML库。
但对于您的具体问题,您应该看看这个项目:http://fivefilters.org/content-only/--这是Readability算法的一个修改版本,它旨在从页面中提取文本内容(而不是页眉和页脚)。
推荐文章
- 使伸缩项目正确浮动
- 形式内联内的形式水平在twitter bootstrap?
- 自定义元素在HTML5中有效吗?
- 如何触发自动填充在谷歌Chrome?
- 创建圈div比使用图像更容易的方法?
- 为什么Chrome浏览器不正确地确定页面是在不同的语言,并提供翻译?
- 原则-如何打印出真正的sql,而不仅仅是准备好的语句?
- 如何从关联PHP数组中获得第一项?
- PHP/MySQL插入一行然后获取id
- 我如何排序一个多维数组在PHP
- 如何在PHP中截断字符串最接近于一定数量的字符?
- PHP错误:“zip扩展名和unzip命令都没有,跳过。”
- Nginx提供下载。php文件,而不是执行它们
- 在网页上用鼠标模拟震颤(例如帕金森病)?
- Bootstrap抛出Uncaught错误:Bootstrap的JavaScript需要jQuery