如何使用Nokogiri获取第一个元素的文本?

时间:2016-09-12 16:31:13

标签: ruby nokogiri

我正在尝试从此HTML获取Last sold date的文字:

<td class="browse-cell-date">

    <span title="Last sold date">
        May 2002 
    </span>

    <button class="btn btn-previous-sales js-btn-previous-sales">
        Previous sales (1) <i class="icon icon-down-open-1"/>
    </button>

    <div class="previous-sales-panel is-hidden">
        <span style="display: block;">
            Aug 1997
            <span class="fright">£60,000</span>
        </span>
    </div>

</td>

我试过了:

    date = val.search(".//td[@class='browse-cell-date']").children[1]

它给了我想要的范围,但在添加.text后,没有返回任何内容。

2 个答案:

答案 0 :(得分:1)

我从:

开始
require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
    <td class="browse-cell-date">

        <span title="Last sold date">
            May 2002 
        </span>

        <button class="btn btn-previous-sales js-btn-previous-sales">
            Previous sales (1) <i class="icon icon-down-open-1"/>
        </button>

        <div class="previous-sales-panel is-hidden">
            <span style="display: block;">
                Aug 1997
                <span class="fright">£60,000</span>
            </span>
        </div>

    </td>
EOT

sold_date = doc.at('span[title="Last sold date"]') # => #<Nokogiri::XML::Element:0x3ffc7e84c35c name="span" attributes=[#<Nokogiri::XML::Attr:0x3ffc7e84c2f8 name="title" value="Last sold date">] children=[#<Nokogiri::XML::Text:0x3ffc7e82bc10 "\n            May 2002 \n        ">]>
sold_date.text # => "\n            May 2002 \n        "
sold_date.text.strip # => "May 2002"

所以

doc.at('span[title="Last sold date"]').text.strip # => "May 2002"

会这样做。

atsearch('some selector').first类似,因此请使用它以方便使用。 atsearch都足够聪明,可以在大多数时间确定选择器是CSS还是XPath,所以我使用它们。如果Nokogiri被愚弄,我将恢复使用其中一个*_css*_xpath变体。

或者你可以使用:

doc.at('td.browse-cell-date span').text.strip # => "May 2002"
doc.at('td.browse-cell-date > span').text.strip # => "May 2002"

注意:将text与任何searchxpathcss方法一起使用并不是一个好主意。这些方法返回一个NodeSet,当你使用它的text方法时,它不能达到预期效果。请考虑以下示例:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<html>
    <body>
        <p>foo</p>
        <p>bar</p>
    </body>
</html>
EOT

doc.search('p').class # => Nokogiri::XML::NodeSet
doc.search('p').text # => "foobar"

我们经常会看到人们做过这些问题的问题,然后需要弄清楚如何将连接的文本拆分成有用的东西,这通常非常困难。

99.99%的时间,您希望使用以下map(&:text)从NodeSet中提取文本:

doc.search('p').map(&:text) # => ["foo", "bar"]

但是,在您的使用中,只需使用at,它会返回一个节点,然后text将执行您期望的操作。

答案 1 :(得分:-2)

试试这个

page.search(".//td").children[1].attr("title")