首页 文章

你如何在PHP中解析和处理HTML / XML?

提问于
浏览
1951

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

29 回答

  • 28

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

  • 7

    Symfony框架具有可以解析HTML的bundle,您可以使用CSS样式来选择DOMs而不是使用XPath .

  • 10

    phpQueryQueryPath在复制流畅的jQuery API方面非常相似 . 's also why they'是在PHP中正确解析HTML的两种最简单的方法 .

    Examples for 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.classDIV 标记选择器 . 但是你也可以使用XPath语句,有时速度更快 . 此外,典型的jQuery方法(如 ->children()->text() ,尤其是 ->attr() )可以简化提取正确的HTML代码段 . (已经解码了他们的SGML实体 . )

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

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

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

    .

    phpQuery or QueryPath?

    通常,QueryPath更适合处理文档 . 虽然phpQuery也实现了一些伪AJAX方法(只是HTTP请求),更接近jQuery . 据说phpQuery通常比QueryPath更快(因为整体功能较少) .

    有关差异的更多信息,请参阅this comparison on the wayback machine from tagbyte.org . (原始来源丢失了,所以这里是一个互联网档案链接 . 是的,你仍然可以找到丢失的页面,人 . )

    这是a comprehensive QueryPath introduction .

    Advantages

    • 简单性和可靠性

    • 简单易用的替代品 ->find("a img, a object, div a")

    • 正确的数据转义(与正则表达式grepping相比)

  • 311

    Native XML Extensions

    我更喜欢使用native XML extensions中的一个,因为它们与PHP捆绑在一起,通常比所有第三方库更快,并且在标记上给我所需的所有控制权 .

    DOM

    DOM扩展允许您使用PHP 5通过DOM API操作XML文档 . 它是W3C的文档对象模型核心级别3的实现,这是一个平台和语言中立的接口,允许程序和脚本动态访问和更新文档的内容,结构和样式 .

    DOM能够解析和修改现实世界(破碎)的HTML,它可以做XPath queries . 它基于libxml .

    使用DOM需要一些时间才能提高效率,但这个时间对IMO来说非常值得 . 由于DOM是一个与语言无关的接口,因此您可以找到多种语言的实现,因此如果您需要更改编程语言,那么您很可能已经知道如何使用该语言的DOM API .

    可以在Grabbing the href attribute of an A element中找到基本用法示例,并且可以在DOMDocument in php找到一般概念概述

    How to use the DOM extension has been covered extensively on StackOverflow,所以如果您选择使用它,您可以确定您遇到的大多数问题都可以通过搜索/浏览Stack Overflow来解决 .

    XMLReader

    XMLReader扩展是一个XML pull解析器 . 读取器在文档流上作为光标前进,并在途中停在每个节点上 .

    与DOM一样,XMLReader基于libxml . 我不知道如何触发HTML Parser模块,因此使用XMLReader解析损坏的HTML的机会可能不如使用DOM,因为您可以明确告诉它使用libxml的HTML Parser Module .

    基本用法示例可在getting all values from h1 tags using php找到

    XML Parser

    此扩展允许您创建XML解析器,然后为不同的XML事件定义处理程序 . 每个XML解析器还有一些您可以调整的参数 .

    XML Parser库也基于libxml,并实现了SAX样式的XML推送解析器 . 它可能是比DOM或SimpleXML更好的内存管理选择,但是比XMLReader实现的pull解析器更难以使用 .

    SimpleXml

    SimpleXML扩展提供了一个非常简单且易于使用的工具集,用于将XML转换为可以使用普通属性选择器和数组迭代器处理的对象 .

    当您知道HTML是有效的XHTML时,SimpleXML是一个选项 . 如果你需要解析破碎的HTML,甚至不要考虑SimpleXml,因为它会窒息 .

    可以在A simple program to CRUD node and node values of xml file找到基本用法示例,并且有lots of additional examples in the PHP Manual .


    3 rd Party Libraries(基于libxml)

    如果您更喜欢使用第三方库,我建议使用实际上使用DOM / libxml而不是字符串解析的库 .

    FluentDom - 回购

    FluentDOM为PHP中的DOMDocument提供类似jQuery的流畅XML接口 . 选择器是用XPath或CSS编写的(使用CSS到XPath转换器) . 当前版本扩展了DOM实现标准接口并添加了DOM Living Standard的功能 . FluentDOM可以加载JSON,CSV,JsonML,RabbitFish等格式 . 可以通过Composer安装 .

    HtmlPageDom

    Wa72 \ HtmlPageDom`是一个用于轻松操作HTML文档的PHP库 . 它需要来自Symfony2组件的DomCrawler来遍历DOM树,并通过添加操作HTML文档的DOM树的方法来扩展它 .

    phpQuery(多年未更新)

    phpQuery是一个服务器端,可链接,CSS3选择器驱动的文档对象模型(DOM)API,基于用PHP5编写的jQuery JavaScript库,并提供额外的命令行界面(CLI) .

    另见:https://github.com/electrolinux/phpquery

    Zend_Dom

    Zend_Dom提供了处理DOM文档和结构的工具 . 目前,我们提供Zend_Dom_Query,它提供统一的界面使用XPath和CSS选择器查询DOM文档 .

    QueryPath

    QueryPath是一个用于操作XML和HTML的PHP库 . 它不仅适用于本地文件,还适用于Web服务和数据库资源 . 它实现了大部分jQuery接口(包括CSS样式选择器),但它经过大量调整以供服务器端使用 . 可以通过Composer安装 .

    fDOMDocument

    fDOMDocument扩展了标准DOM,以便在所有错误情况下使用异常,而不是PHP警告或通知 . 为方便起见,他们还添加了各种自定义方法和快捷方式,并简化了DOM的使用 .

    saber / xml

    saber / xml是一个包装和扩展XMLReader和XMLWriter类的库,用于创建一个简单的“xml到对象/数组”映射系统和设计模式 . 编写和读取XML是单遍的,因此可以快速并且需要大型xml文件的低内存 .

    FluidXML

    FluidXML是一个用于使用简洁流畅的API来操作XML的PHP库 . 它利用XPath和流畅的编程模式,既有趣又有效 .


    3 rd-Party(不是基于libxml的)

    构建DOM / libxml的好处是,您可以获得良好的开箱即用性能,因为您基于本机扩展 . 但是,并非所有第三方库都沿着这条路线行进 . 其中一些列在下面

    PHP简单的HTML DOM解析器

    用PHP5编写的HTML DOM解析器允许您以非常简单的方式操作HTML!需要PHP 5 . 支持无效的HTML . 使用选择器在HTML页面上查找标签,就像jQuery一样 . 从一行中提取HTML中的内容 .

    我一般不推荐这个解析器 . 代码库很糟糕,解析器本身很慢而且内存很耗 . 并非所有jQuery选择器(例如child selectors)都是可能的 . 任何基于libxml的库都应该比这更容易 .

    PHP Html Parser

    PHPHtmlParser是一个简单,灵活的html解析器,允许您使用任何css选择器(如jQuery)选择标签 . 目标是协助开发需要快速,简单的方法来废弃html的工具,无论它是否有效!这个项目是由sunra / php-simple-html-dom-parser原创支持的,但支持似乎已经停止,所以这个项目是我对他以前工作的改编 .

    同样,我不推荐这个解析器 . CPU使用率很高,速度相当慢 . 还没有清除已创建DOM对象的内存的功能 . 这些问题尤其适用于嵌套循环 . 文档本身不准确且拼写错误,自4月14日以来没有对修复的响应 .

    Ganon

    通用标记器和HTML / XML / RSS DOM解析器能够操作元素及其属性支持无效的HTML和UTF8可以对元素执行类似CSS3的高级查询(如jQuery - 支持的命名空间)HTML美化器(如HTML Tidy)Minify CSS和Javascript排序属性,更改字符大小写,纠正缩进等 . 使用基于当前字符/令牌的回调的可扩展解析文档在较小的函数中分离的操作,以便轻松覆盖快速简便

    从未使用过它 . 不知道它是否有用 .


    HTML 5

    您可以使用上面的解析HTML5,但由于HTML5允许的标记,there can be quirks . 因此,对于HTML5,您要考虑使用专用解析器,例如

    html5lib

    基于WHATWG HTML5规范的HTML解析器的Python和PHP实现,可与主要桌面Web浏览器实现最大兼容性 .

    HTML5最终确定后,我们可能会看到更多专用解析器 . W3的 Headers 为How-To for html 5 parsing的博客文章值得一试 .


    WebServices

    如果您不想编写PHP,也可以使用Web服务 . 一般来说,我发现这些实用程序的效用很小,但这只是我和我的用例 .

    YQL

    YQL Web服务使应用程序能够在Internet上查询,过滤和组合来自不同来源的数据 . YQL语句具有类似SQL的语法,对于具有数据库经验的任何开发人员来说都很熟悉 .

    ScraperWiki .

    ScraperWiki的外部界面允许您以您希望在Web或您自己的应用程序中使用的形式提取数据 . 您还可以提取有关任何刮刀状态的信息 .


    正则表达式

    Last和 least recommended ,您可以使用regular expressions从HTML中提取数据 . 通常,不鼓励在HTML上使用正则表达式 .

    您在网上找到的大多数与标记相匹配的片段都很脆弱 . 在大多数情况下,它们只适用于非常特殊的HTML . 微小的标记更改,例如在某处添加空格,或添加或更改标记中的属性,可能会导致RegEx在未正确编写时失败 . 在HTML上使用RegEx之前,您应该知道自己在做什么 .

    HTML解析器已经知道HTML的语法规则 . 必须为您编写的每个新RegEx讲授正则表达式 . RegEx在某些情况下很好,但它确实取决于你的用例 .

    你是can write more reliable parsers,但是当前面提到的库已经存在并且在这方面做得更好时,用正则表达式编写一个完整可靠的自定义解析器是浪费时间的 .

    另见Parsing Html The Cthulhu Way


    书籍

    如果你想花一些钱,看看吧

    我不隶属于PHP Architect或作者 .

  • 18

    我推荐PHP Simple HTML DOM Parser .

    它确实有很好的功能,例如:

    foreach($html->find('img') as $element)
           echo $element->src . '<br>';
    
  • 17

    只需使用DOMDocument->loadHTML()并完成它 . libxml的HTML解析算法非常好而且速度快,而且与普遍看法相反,它不会阻碍格式错误的HTML .

  • 9

    我创建了一个名为PHPPowertools/DOM-Query的库,它允许您像使用jQuery一样抓取HTML5和XML文档 .

    在引擎盖下,它使用symfony/DomCrawler将CSS选择器转换为XPath选择器 . 即使将一个对象传递给另一个对象,它也始终使用相同的DomDocument,以确保良好的性能 .


    使用示例:

    namespace PowerTools;
    
    // Get file content
    $htmlcode = file_get_contents('https://github.com');
    
    // Define your DOMCrawler based on file string
    $H = new DOM_Query($htmlcode);
    
    // Define your DOMCrawler based on an existing DOM_Query instance
    $H = new DOM_Query($H->select('body'));
    
    // Passing a string (CSS selector)
    $s = $H->select('div.foo');
    
    // Passing an element object (DOM Element)
    $s = $H->select($documentBody);
    
    // Passing a DOM Query object
    $s = $H->select( $H->select('p + p'));
    
    // Select the body tag
    $body = $H->select('body');
    
    // Combine different classes as one selector to get all site blocks
    $siteblocks = $body->select('.site-header, .masthead, .site-body, .site-footer');
    
    // Nest your methods just like you would with jQuery
    $siteblocks->select('button')->add('span')->addClass('icon icon-printer');
    
    // Use a lambda function to set the text of all site blocks
    $siteblocks->text(function( $i, $val) {
        return $i . " - " . $val->attr('class');
    });
    
    // Append the following HTML to all site blocks
    $siteblocks->append('<div class="site-center"></div>');
    
    // Use a descendant selector to select the site's footer
    $sitefooter = $body->select('.site-footer > .site-center');
    
    // Set some attributes for the site's footer
    $sitefooter->attr(array('id' => 'aweeesome', 'data-val' => 'see'));
    
    // Use a lambda function to set the attributes of all site blocks
    $siteblocks->attr('data-val', function( $i, $val) {
        return $i . " - " . $val->attr('class') . " - photo by Kelly Clark";
    });
    
    // Select the parent of the site's footer
    $sitefooterparent = $sitefooter->parent();
    
    // Remove the class of all i-tags within the site's footer's parent
    $sitefooterparent->select('i')->removeAttr('class');
    
    // Wrap the site's footer within two nex selectors
    $sitefooter->wrap('<section><div class="footer-wrapper"></div></section>');
    
    [...]
    

    支持的方法:


    • 由于显而易见的原因重命名为'select'

    • 重命名为'void',因为'empty'是PHP中的保留字


    注意:

    该库还包含自己的零配置自动加载器,用于PSR-0兼容库 . 包含的示例应该开箱即用,无需任何其他配置 . 或者,您可以将它与作曲家一起使用 .

  • 54

    XML_HTMLSax相当稳定 - 即使它不再维持 . 另一种选择可能是通过Html Tidy管道HTML,然后使用标准XML工具解析它 .

  • 139

    有许多方法可以处理HTML / XML DOM,其中大多数已经提到过 . 因此,我不会尝试自己列出这些 .

    我只是想补充一点,我个人更喜欢使用DOM扩展,为什么:

    • iit充分利用了底层C代码的性能优势

    • 它是OO PHP(并允许我将其子类化)

    • 它的级别相当低(这使我可以将它用作更高级行为的非膨胀基础)

    • 它提供对DOM的每个部分的访问(与例如SimpleXml不同,它忽略了一些鲜为人知的XML特性)

    • 它有一个用于DOM抓取的语法,类似于本机Javascript中使用的语法 .

    虽然我错过了为 DOMDocument 使用CSS选择器的能力,但是有一种相当简单方便的方法来添加此功能:继承 DOMDocument 并将类似JS的 querySelectorAllquerySelector 方法添加到子类中 .

    为了解析选择器,我建议使用Symfony framework中非常简约的CssSelector component . 该组件只是将CSS选择器转换为XPath选择器,然后可以将其输入 DOMXpath 以检索相应的Nodelist .

    然后,您可以使用此(仍然非常低级别)子类作为更高级别类的基础,例如 . 解析非常特定类型的XML或添加更多类似jQuery的行为 .

    下面的代码直接来自我的DOM-Query library并使用我描述的技术 .

    对于HTML解析:

    namespace PowerTools;
    
    use \Symfony\Component\CssSelector\CssSelector as CssSelector;
    
    class DOM_Document extends \DOMDocument {
        public function __construct($data = false, $doctype = 'html', $encoding = 'UTF-8', $version = '1.0') {
            parent::__construct($version, $encoding);
            if ($doctype && $doctype === 'html') {
                @$this->loadHTML($data);
            } else {
                @$this->loadXML($data);
            }
        }
    
        public function querySelectorAll($selector, $contextnode = null) {
            if (isset($this->doctype->name) && $this->doctype->name == 'html') {
                CssSelector::enableHtmlExtension();
            } else {
                CssSelector::disableHtmlExtension();
            }
            $xpath = new \DOMXpath($this);
            return $xpath->query(CssSelector::toXPath($selector, 'descendant::'), $contextnode);
        }
    
        [...]
    
        public function loadHTMLFile($filename, $options = 0) {
            $this->loadHTML(file_get_contents($filename), $options);
        }
    
        public function loadHTML($source, $options = 0) {
            if ($source && $source != '') {
                $data = trim($source);
                $html5 = new HTML5(array('targetDocument' => $this, 'disableHtmlNsInDom' => true));
                $data_start = mb_substr($data, 0, 10);
                if (strpos($data_start, '<!DOCTYPE ') === 0 || strpos($data_start, '<html>') === 0) {
                    $html5->loadHTML($data);
                } else {
                    @$this->loadHTML('<!DOCTYPE html><html><head><meta charset="' . $encoding . '" /></head><body></body></html>');
                    $t = $html5->loadHTMLFragment($data);
                    $docbody = $this->getElementsByTagName('body')->item(0);
                    while ($t->hasChildNodes()) {
                        $docbody->appendChild($t->firstChild);
                    }
                }
            }
        }
    
        [...]
    }
    

    另见Symfony的创建者Fabien Potencier关于他决定为Symfony创建CssSelector组件以及如何使用它的Parsing XML documents with CSS selectors .

  • 16

    对于HTML5,html5 lib已经被废弃多年了 . 我能找到的唯一一个带有最新更新和维护记录的HTML5库是html5-php,它刚刚在一周之前被带到beta 1.0 .

  • 17

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

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

  • 6

    Advanced Html Dom是一个简单的HTML DOM替代品,提供相同的接口,但它是基于DOM的,这意味着不会发生任何相关的内存问题 .

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

  • 127

    使用FluidXML,您可以使用 XPathCSS Selectors 查询和迭代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

  • 2

    来自XML的JSON和数组有三行:

    $xml = simplexml_load_string($xml_string);
    $json = json_encode($xml);
    $array = json_decode($json,TRUE);
    

    塔达!

  • 0

    有几个原因不能通过正则表达式解析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/")));
    
  • 1767

    Why you shouldn't and when you should use regular expressions?

    首先,一个常见的误称:Regexps不适用于“ parsing ”HTML . 但是,正则表达式可以是“ extract ”数据 . 提取是他们的目标 . 正则表达式HTML提取优于正确的SGML工具包或基线XML解析器的主要缺点是它们的语法功能和不同的可靠性 .

    考虑制作一个有点可靠的HTML提取正则表达式:

    <a\s+class="?playbutton\d?[^>]+id="(\d+)".+?    <a\s+class="[\w\s]*title
    [\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?
    

    比简单的phpQuery或QueryPath等价物更不易读:

    $div->find(".stationcool a")->attr("title");
    

    但是有一些具体的用例,他们可以提供帮助 .

    • 许多DOM遍历前端不会显示HTML注释 <!-- ,但有时它们是提取的更有用的锚点 . 特别是伪HTML变体 <$var> 或SGML残差很容易用正则表达式来驯服 .

    • 正则表达式通常可以节省后期处理 . 但是,HTML实体通常需要手动处理 .

    • 最后,对于非常简单的任务,例如提取<img src = urls,它们实际上是一个可能的工具 . 与SGML / XML解析器相比,速度优势通常只适用于这些非常基本的提取过程 .

    有时甚至建议使用正则表达式 /<!--CONTENT-->(.+?)<!--END-->/ 预先提取HTML片段,并使用更简单的HTML解析器前端处理剩余部分 .

    Note: 我实际上有app,我在那里使用XML解析和正则表达式 . 就在上周PyQuery解析破了,正则表达式仍然有效 . 是的很奇怪,我自己无法解释 . 但事情发生了 .
    所以请不要与正则表达式=邪恶的模因相匹配 . But let's also not vote this up too much. It's just a sidenote for this topic.

  • 13

    使用DOM而不是字符串解析的SimpleHtmlDom的第三方替代方案:phpQueryZend_DomQueryPathFluentDom .

  • 23

    我编写了一个通用的XML解析器,可以轻松处理GB文件 . 它基于XMLReader,使用起来非常简单:

    $source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
    foreach ($source as $tag) {
        echo $tag->field1;
        echo $tag->field2->subfield1;
    }
    

    这是github回购:XmlExtractor

  • 11

    您可以尝试使用类似HTML Tidy之类的东西来清理任何"broken" HTML并将HTML转换为XHTML,然后您可以使用XML解析器进行解析 .

  • 225

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

  • 23

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

    simplehtmldom.sourceforge

    它以面向对象的方式处理DOM元素,并且新的迭代对非兼容代码有很多覆盖 . 还有一些很棒的函数,比如你在JavaScript中看到的,比如“find”函数,它将返回该标记名称的所有元素实例 .

    我已经在许多工具中使用它,在许多不同类型的网页上测试它,我认为它很有用 .

  • 14

    对于1a和2:我将投票支持新的Symfony Componet类DOMCrawler(DomCrawler) . 此类允许类似于CSS选择器的查询 . 看一下这个演示文稿,了解真实世界的例子:news-of-the-symfony2-world .

    该组件设计为独立工作,无需Symfony即可使用 .

    唯一的缺点是它只适用于PHP 5.3或更高版本 .

  • 51

    我们之前已经为我们的需求创建了很多爬虫 . 在一天结束时,通常是简单的正则表达式来做最好的事情 . 虽然上面列出的库是好的,但是如果你知道你在寻找什么,正则表达式是一个更安全的方法,因为你也可以处理无效的HTML / XHTML结构,如果加载会失败通过大多数解析器 .

  • 58

    是的,你可以使用simple_html_dom来达到目的 . 但是我在simple_html_dom上做了很多工作,特别是对于网页报废,并且发现它太脆弱了 . 它完成了基本工作,但我不会推荐它 .

    我从来没有使用卷曲,但我学到的是卷曲可以更有效地完成工作并且更加坚固 .

    请看看这个链接:scraping-websites-with-curl

  • 85

    试试Simple HTML DOM Parser

    • 用PHP 5编写的HTML DOM解析器,允许您以非常简单的方式操作HTML!

    • 需要PHP 5 .

    • 支持无效的HTML .

    • 使用选择器在HTML页面上查找标签,就像jQuery一样 .

    • 从一行中提取HTML中的内容 .

    • Download

    示例:

    如何获取HTML元素:

    // Create DOM from URL or file
    $html = file_get_html('http://www.example.com/');
    
    // Find all images
    foreach($html->find('img') as $element)
           echo $element->src . '<br>';
    
    // Find all links
    foreach($html->find('a') as $element)
           echo $element->href . '<br>';
    

    如何修改HTML元素:

    // Create DOM from string
    $html = str_get_html('<div id="hello">Hello</div><div id="world">World</div>');
    
    $html->find('div', 1)->class = 'bar';
    
    $html->find('div[id=hello]', 0)->innertext = 'foo';
    
    echo $html;
    

    从HTML中提取内容:

    // Dump contents (without tags) from HTML
    echo file_get_html('http://www.google.com/')->plaintext;
    

    Scraping Slashdot:

    // Create DOM from URL
    $html = file_get_html('http://slashdot.org/');
    
    // Find all article blocks
    foreach($html->find('div.article') as $article) {
        $item['title']     = $article->find('div.title', 0)->plaintext;
        $item['intro']    = $article->find('div.intro', 0)->plaintext;
        $item['details'] = $article->find('div.details', 0)->plaintext;
        $articles[] = $item;
    }
    
    print_r($articles);
    
  • 40

    如果您熟悉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或缺少引号 .

  • 37

    我创建了一个名为HTML5DOMDocument的库,可以在https://github.com/ivopetkov/html5-dom-document-php免费获得 .

    它也支持查询选择器,我认为在您的情况下将非常有用 . 这是一些示例代码:

    $dom = new IvoPetkov\HTML5DOMDocument();
    $dom->loadHTML('<!DOCTYPE html><html><body><h1>Hello</h1><div class="content">This is some text</div></body></html>');
    echo $dom->querySelector('h1')->innerHTML;
    
  • 11

    顺便说一句,这通常被称为 screen scraping . 我用过的库是Simple HTML Dom Parser .

  • 35

    QueryPath很好,但如果你没有工作,请注意"tracking state"原因 .

    这意味着结果集上的每个调用都会修改对象中的结果集,它不像jquery中那样可链接,其中每个链接都是一个新集合,你有一个集合,它是查询的结果,每个函数调用都会修改那一套 .

    为了获得类似jquery的行为,你需要在进行过滤/修改之类的操作之前进行分支,这意味着它将更加密切地反映jquery中发生的事情 .

    $results = qp("div p");
    $forename = $results->find("input[name='forename']");
    

    $results 现在包含 input[name='forename'] 的结果集而不是原始查询 "div p" 这让我大吃一惊,我发现QueryPath跟踪过滤器并查找修改结果并将其存储在对象中的所有内容 . 你需要这样做

    $forename = $results->branch()->find("input[name='forname']")
    

    然后 $results 基本上就像我发现的那样赢得了't be modified and you can reuse the result set again and again, perhaps somebody with much more knowledge can clear this up a bit, but it' .

相关问题