GVKun编程网logo

HTML XPath:提取与多个标签混合的文本?(xpath获取html文本包括标签)

14

本文将介绍HTMLXPath:提取与多个标签混合的文本?的详细情况,特别是关于xpath获取html文本包括标签的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将

本文将介绍HTML XPath:提取与多个标签混合的文本?的详细情况,特别是关于xpath获取html文本包括标签的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于html – Nokogiri和Xpath:找到两个标签之间的所有文本、html – XPATH获取所有标签没有和标签、html – XPath:选择self并跟随兄弟姐妹、html – 为什么我的XPath不会根据其标签文本选择链接/按钮?的知识。

本文目录一览:

HTML XPath:提取与多个标签混合的文本?(xpath获取html文本包括标签)

HTML XPath:提取与多个标签混合的文本?(xpath获取html文本包括标签)

目标:从特定元素(例如li)中提取文本,而忽略各种混合在标签中的内容,即展平第一级子级,并简单地分别返回每个展平型子级的串联文本。

例:

<div id="mw-content-text"><h2><span>CIA</span></h2>    <ol>    <li>Central <a href="/Intelligence_Agency.html">Intelligence Agency</a>.</li>    <li>Culinary <a href="/Institute.html">Institute</a> of <a href="/America.html">America</a>.</li>    </ol>    </Div>  

所需文字:

  • Central Intelligence Agency
  • Culinary Institute of America

除了周围的定位标记阻止简单的检索。

为了分别返回每个li标签,我们使用简单的方法:

//div[contains(@id,"mw-content-text")]/ol/li

但这还包括周围的锚标签等。

//div[contains(@id,"mw-content-text")]/ol/li/text()

仅返回属于li的直接子元素的文本元素,即’Central’,’.’…

然后寻找自我和后代的文本元素似乎合乎逻辑

//div[contains(@id,"mw-content-text")]/ol/li[descendant-or-self::text]

但这根本没有任何回报!

有什么建议?我正在使用Python,因此可以使用其他模块进行后期处理。

(我正在使用似乎符合XPath 1.0的Scrapy HtmlXPathSelector)

答案1

小编典典

有一个小问题:

//div[contains(@id,"mw-content-text")]/ol/li[descendant-or-self::text]

正确的表达式是:

//div[contains(@id,"mw-content-text")]/ol/li[descendant-or-self::text()]

但是,有一个更简单的表达式可以精确生成指定文本下所有文本节点的所需连接li

string(//div[contains(@id,"mw-content-text")]/ol/li)

html – Nokogiri和Xpath:找到两个标签之间的所有文本

html – Nokogiri和Xpath:找到两个标签之间的所有文本

我不确定这是语法问题还是版本差异,但我似乎无法解决这个问题.我想从h2标签中取出(非关闭)td内的数据到h3标签.以下是HTML的外观.
<td valign="top" width="350">
    <br><h2>NameIWant</h2><br>
    <br>Town<br>

    PhoneNumber<br>
    <a href="mailto:emailIwant@Nowhere.com">emailIwant@Nowhere.com</a>
    <br>
    <a href="http://websiteIwant.com">websiteIwant.com</a>
    <br><br>    
    <br><img src="images/spacer.gif"/><br>

    <h3><b>I want to stop before this!</b></h3>
    Lorem Ipsum Yadda Yadda<br>
    <img src="images/spacer.gif" border="0" width="20" height="11" alt=""/><br>
    <td width="25">
        <img src="images/spacer.gif" border="0" width="20" height="8" alt=""/>
        <td valign="top" width="200"><img src="images/spacer.gif"/>
            <br>
            <br>

            <table cellspacing="0" cellpadding="0" border="0"/>205"&gt;<tr><td>
                <a href="http://dontneedthis.com">
                </a></td></tr><br>
            <table border="0" cellpadding="3" cellspacing="0" width="200">
            ...

< td valign>直到页面的最底部才关闭,我认为这可能是我遇到问题的原因.

我的Ruby代码看起来像:

require 'open-uri'
require 'nokogiri'

@doc = Nokogiri::XML(open("http://www.url.com"))

content = @doc.css('//td[valign="top"] [width="350"]')

name = content.xpath('//h2').text
puts name // Returns NameIwant

townNumberLinks = content.search('//following::h2')
puts content // Returns <h2> NameIWant </h2>

据我所知,遵循语法应该“在当前节点的结束标记之后选择文档中的所有内容”.如果我尝试使用前面的:

townNumberLinks = content.search('//preceding::h3')
// I get: <h3><b>I want to stop before this!</b></h3>

希望我明确表达了我想要做的事情.谢谢!

解决方法

这不是微不足道的.在您选择的节点(td)的上下文中,要获取两个元素之间的所有内容,您需要执行这两个集合的交集:

>集合A:第一个h3之前的所有节点:// h3 [1] / preceding :: node()
> Set B:第一个h2:// h2 [1] / following :: node()之后的所有节点

要执行交叉路口,您可以使用Kaysian method(Michael Kay之后,谁提出它).基本公式是:

A[count(.|B) = count(B)]

将它应用于您的集合,如上所定义,其中A = // h3 [1] / preceding :: node()和B = // h2 [1] / following :: node(),我们有:

//h3[1]/preceding::node()[ count( . | //h2[1]/following::node()) = count(//h2[1]/following::node()) ]

这将选择从第一个< br>开始的所有元素和文本节点.在< / h2>之后标记,到最后一个< br>之后的空白文本节点,就在下一个< h3>之前.标签.

您可以轻松选择h2和h3之间的文本节点,替换表达式中text()的node().这个将返回两个标头之间的所有文本节点(包括空格和换行符):

//h3[1]/preceding::text()[ count( . | //h2[1]/following::text()) = count(//h2[1]/following::text()) ]

html – XPATH获取所有标签没有和标签

html – XPATH获取所有标签没有和标签

我有一些问题,没有< script>获取所有的html标签或者< script ... />使用Xpath.

例如,在HTML代码的这一部分中,我想删除:

<script type="text/javascript" src="http://www.google.com/coop/cse/brand?form=cse-search-Box&amp;lang=fr"/>

这个代码

<li><!-- Search Google -->
<center>
                     <form action="http://www.google.fr/cse" id="cse-search-Box" target="_blank">
                        <div>
                           <input type="hidden" name="cx" value="partner-pub-0959382714089534:mw3ssl65jk1"/>
                           <input type="hidden" name="ie" value="ISO-8859-1"/>
                           <input type="text" name="q" size="31"/>
                           <input type="submit" name="sa" value="Rechercher"/>
                        </div>
                     </form>
                     <script type="text/javascript"
                             src="http://www.google.com/coop/cse/brand?form=cse-search-Box&amp;lang=fr"/>
                  </center>
                  <!-- Search Google --></li>

我正在使用Web-Harvest生成一个xml文件,然后我必须删除一些特定标签.
我尝试了很多xpath(我正在使用html的主体):

> // body // * [not(name()=’script’)]
> // body // * [not(self :: script)]
> // body // * [not(starts-with(name(),’script’))]
> // body // * [not(contains(name(),’script’))]

但它不起作用.

请注意// body // * [name()=’script’]正在工作,但我希望相反……

你有什么想法吗?

或者更常见,如果您知道如何删除所有< script> <脚本/>标签使用Xpath,我也有兴趣:-)

提前致谢.

解决方法

首先,XPath选择现有文档中的节点,但不会删除它们.而你开始的路径// body // *选择body元素的所有子元素和后代元素.即使你现在添加一个像// body // * [not(self :: script)]这样的谓词,该路径仍然会选择像li和center元素这样的元素,这些元素本身不是脚本元素,但包含一个脚本元素.所以// body // * [not(self :: script)]是不选择任何非脚本元素的正确方法,但如果你想要删除脚本元素的原始中心元素,它就无济于事.这不是纯XPath可以为您做的事情,您需要转移到XSLT来转换文档,这样就可以删除任何脚本元素.

html – XPath:选择self并跟随兄弟姐妹

html – XPath:选择self并跟随兄弟姐妹

<div>
    <dt>
        Test 1
    </dt>
    <dd>
    </dd>
    <dt>
        Test 2
    </dt>
    <dd>
    </dd>
</div>

到目前为止我已经编写了这个XPath

//dt[contains(text(),"Test")]/self::dt|following-sibling::dd

但这并没有带来dt和dd,只是dt.

解决方法

如果它必须是单个XPath 1.0表达式,那么你将不得不说

//dt[contains(.,'Test')] | //dt[contains(.,'Test')]/following-sibling::dd[1]

最后的[1]很重要,因为没有它会提取所有dd元素,这些元素遵循包含“测试”的dt,即给出

<div>
    <dt>
        Test 1
    </dt>
    <dd>
        Foo
    </dd>
    <dt>
        Something else 2
    </dt>
    <dd>
        Bar
    </dd>
</div>

没有[1]的版本将匹配三个节点,dt包含“Test 1”以及“Foo”和“Bar”dd元素.使用[1],您将只能正确地获得“Test 1”和“Foo”.

但是,根据您使用XPath的确切方式,首先选择可能会更清楚

//dt[contains(.,'Test')]

然后迭代匹配的节点,并进行评估

. | following-sibling::dd[1]

依次在每个节点的上下文中.

html – 为什么我的XPath不会根据其标签文本选择链接/按钮?

html – 为什么我的XPath不会根据其标签文本选择链接/按钮?

<a href="javascript:void(0)" title="home">
    <span>Maybe more text here</span>
    Home
</a>

因此,对于上面的代码,当我将// a编写为XPath时,它会突出显示,但是当我编写// a [contains(text(),’Home’)]时,它不会突出显示.我认为这很简单,应该有效.

哪里是我的错?

解决方法

其他答案错过了这里的实际问题:

>是的,你可以在@title上匹配,但这不是OP的原因
XPath在以前可能已经运行的地方失败了.
>是的,XML和XPath区分大小写,所以Home不一样
home,但是有一个Home文本节点作为a的子节点,所以OP就是
如果他不相信@title出席,则有权使用Home.

真正的问题

OP的XPath,

//a[contains(text(),'Home')]

说要选择第一个文本节点包含子串Home的所有元素.然而,第一个文本节点只包含空格.

说明:text()选择上下文节点的所有子文本节点,a.当contains()被赋予多个节点作为其第一个参数时,它将获取第一个节点的字符串值,但Home出现在第二个文本节点中,而不是第一个节点.

相反,OP应该使用这个XPath,

//a[text()[contains(.,'Home')]]

表示选择所有带有字符串值包含子字符串Home的文本子元素的元素.

如果没有周围的空格,则可以使用此XPath来测试相等而不是子字符串包含:

//a[text()[.='Home']]

或者,对于周围的空白,可以使用此XPath将其修剪掉:

//a[text()[normalize-space()= 'Home']]

也可以看看:

> Testing text() nodes vs string values in XPath
> Why is XPath unclean constructed? Why is text() not needed in predicate?
> XPath: difference between dot and text()

我们今天的关于HTML XPath:提取与多个标签混合的文本?xpath获取html文本包括标签的分享已经告一段落,感谢您的关注,如果您想了解更多关于html – Nokogiri和Xpath:找到两个标签之间的所有文本、html – XPATH获取所有标签没有和标签、html – XPath:选择self并跟随兄弟姐妹、html – 为什么我的XPath不会根据其标签文本选择链接/按钮?的相关信息,请在本站查询。

本文标签: