【问题标题】:Screen Scraping with PHP and XPath使用 PHP 和 XPath 进行屏幕抓取
【发布时间】:2009-01-07 13:31:48
【问题描述】:

有谁知道在使用 XPath 提取数据时如何维护文本格式?

我目前正在提取所有块

<div class="info"> <h5>title</h5> text <a href="somelink">anchor</a> </div>

从一个页面。问题是当我访问 nodeValue 时,我只能得到纯文本。如何捕获包括格式在内的内容,即代码中的 h5 和 a still?

提前致谢。我在 Google 上搜索了所有可以想象的组合,但没有运气。

【问题讨论】:

    标签: php xpath screen-scraping


    【解决方案1】:

    如果您将它作为 DomElement $element 作为 DomDocument $dom 的一部分,那么您将需要执行以下操作:

    $string = $dom->saveXml($element);
    

    元素的 NodeValue 实际上是文本值,而不是结构化的 XML。

    【讨论】:

      【解决方案2】:

      我想添加到 Ciaran McNulty 的答案

      您可以在 SimpleXml 中执行相同的操作,例如:

      $simplexml->node->asXml(); // saveXml() is now an alias
      

      并扩展报价

      元素的 NodeValue 实际上是文本值,而不是结构化的 XML。

      你可以这样想你的节点:

      <div class="info">
          <__toString()> </__toString()>
          <h5>title</h5>
          <__toString()> text </__toString()>
          <a href="somelink">anchor</a>
          <__toString()> </__toString()>
      </div>
      

      $element-&gt;nodeValue 的调用就像调用$element-&gt;__toString() 一样,只会得到__toString() 元素。我创建的虚构__toString() 正式定义为XML_TEXT_NODE

      【讨论】:

        【解决方案3】:

        XPath language 旨在嵌入到另一种语言(如 DOM API、XSLT、XQuery 等)中,不能单独使用。原始问题没有指定所需的嵌入是什么。

        下面是在XSLT中嵌入XPath时的一个非常简单简短的解决方案

        这种转变

        <xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
         <xsl:output omit-xml-declaration="yes"/>
        
            <xsl:template match="div[@class='info']">
               <xsl:copy-of select="."/>
            </xsl:template>
        </xsl:stylesheet>
        

        应用于此 xml 文档时

        <html>
            <body>
                <div class="info">
                    <h1>title1</h1> text1
                    <a href="somelink1">anchor1</a>
                </div>
                Something else here
                <div class="info">
                    <h2>title2</h2> text2
                    <a href="somelink2">anchor2</a>
                </div>
                Something else here
                <div class="info">
                    <h3>title3</h3> text3
                    <a href="somelink3">anchor3</a>
                </div>
            </body>
        </html>
        

        产生想要的结果

        <div class="info">
          <h1>title1</h1> text1
            <a href="somelink1">anchor1</a>
        </div>
                Something else here
        <div class="info">
          <h2>title2</h2> text2
          <a href="somelink2">anchor2</a>
        </div>
                Something else here
        <div class="info">
          <h3>title3</h3> text3
          <a href="somelink3">anchor3</a>
        </div>
        

        【讨论】:

          【解决方案4】:

          您需要确保您的 xpath 查询“结束”在 &lt;div class="info"&gt;。但是,由于 XPath 的工作方式,您仍然会在单独的节点中获得所有“子标签”。您只需要将它们连接起来。

          您也可以使用 XPath 的 join 功能,不过,由于我没有使用过它,我不能说您可能会遇到什么问题。

          【讨论】:

            【解决方案5】:

            div/node() 应该可以解决问题。

            示例输入:

            <div class="info">
              some <h5>title</h5> text <a href="somelink">anchor</a> more text
            </div>
            

            XSLT 样式表示例:

            <?xml version="1.0" encoding="utf-8"?>
            <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            
            <xsl:template match="/">
                    <newtag>
                            <xsl:copy-of select="div/node()"/>
                    </newtag>
            </xsl:template>
            
            </xsl:stylesheet>
            

            示例输出:

            <?xml version="1.0" encoding="utf-8"?>
            <newtag> some<h5>title</h5> text <a href="somelink">anchor</a> more text</newtag>
            

            【讨论】:

              猜你喜欢
              • 2011-07-21
              • 2013-03-02
              • 1970-01-01
              • 2010-09-16
              • 1970-01-01
              • 2011-06-09
              • 1970-01-01
              • 2011-01-12
              • 2013-12-31
              相关资源
              最近更新 更多