如何使用 Nokogiri 获取第一个元素的文本?
How can I get the first element's text using 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
之后,没有返回任何东西。
试试这个
page.search(".//td").children[1].attr("title")
我会从:
开始
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"
会做的。
at
类似于 search('some selector').first
所以为了方便起见使用它。 at
和 search
都足够聪明,可以在大多数情况下判断选择器是 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
与任何 search
、xpath
或 css
方法一起使用都不是一个好主意。这些方法 return 一个 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
,其中 return 是一个节点,然后 text
将执行您期望的操作。
我正在尝试从 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
之后,没有返回任何东西。
试试这个
page.search(".//td").children[1].attr("title")
我会从:
开始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"
会做的。
at
类似于 search('some selector').first
所以为了方便起见使用它。 at
和 search
都足够聪明,可以在大多数情况下判断选择器是 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
与任何 search
、xpath
或 css
方法一起使用都不是一个好主意。这些方法 return 一个 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
,其中 return 是一个节点,然后 text
将执行您期望的操作。