如何從一個或多個節點提取文字

如何正確地從節點中提取文字是我們看到的最受歡迎的問題之一,並且通過濫用 Nokogiri 的搜尋方法幾乎總是變得更加困難。

Nokogiri 支援使用 CSS 和 XPath 選擇器。這些是等價的:

doc.at('p').text   # => "foo"
doc.at('//p').text # => "foo"

doc.search('p').size   # => 2
doc.search('//p').size # => 2

為方便起見,CSS 選擇器擴充套件了許多 jQuery 的 CSS 擴充套件

atsearch 是仿製藥 at_cssat_xpath 沿 cssxpath 。Nokogiri 嘗試確定是否傳入了 CSS 或 XPath 選擇器。可以建立一個選擇器來欺騙 atsearch,因此偶爾會誤解,這就是為什麼我們有更具體的方法版本。一般來說,我幾乎總是使用通用版本,如果我認為 Nokogiri 會誤解,只使用特定版本。這種做法屬於“ 三德 ” 的第一個條目。

如果你要搜尋一個特定節點並想要其文字,請使用 at 或其中一個 at_cssat_xpath 變體:

require 'nokogiri'

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

doc.at('p').text # => "foo"

at 相當於 search(...).first,所以你可以使用更長的版本,但為什麼呢?

如果在使用 searchcssxpath 之後連線的文字被連線起來,那麼新增 map(&:text) 而不是簡單地使用 text

require 'nokogiri'

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

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

有關其他資訊,請參閱 NodeSetNodetext 文件。