Nokogiriは、主に2つのタイプの検索をサポートしていsearch
ますat
。search
NodeSetを返します。これは、配列のように考える必要があります。at
ノードを返します。CSSまたはXPath式を使用できます。CSSの方が読みやすいので、私はCSSの方が好きですが、CSSを使用すると目的の場所に簡単に到達できない場合があるため、もう一方を試してください。
質問の場合は、を使用して、テキストを抽出するノードを指定することが重要ですtext
。結果が広すぎる場合は、必要なタグ内のテキストに加えて、タグ間からテキストを取得します。読み込もうとしているものへの最も直接的なノードへのドリルダウンを回避するには、次のようにします。
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<release>
<artists>
<artist>
<name>Johnny Mnemonic</name>
</artist>
<artist>
<name>Constantine</name>
</artist>
<artists>
<release>
EOT
これらはname
ノードを具体的に探すため、必要なテキストはゴミなしで簡単に取得できます。
doc.at('name').text # => "Johnny Mnemonic"
doc.at('artist name').text # => "Johnny Mnemonic"
doc.at('artists artist name').text # => "Johnny Mnemonic"
これらはより緩い検索であるため、より多くのジャンクが返されます。
doc.at('artist').text # => "\n Johnny Mnemonic\n "
doc.at('artists').text # => "\n \n Johnny Mnemonic\n \n \n Constantine\n \n \n\n"
を使用するとsearch
、複数のノードが返されます。
doc.search('name').map(&:text)
[
[0] "Johnny Mnemonic",
[1] "Constantine"
]
doc.search('artist').map(&:text)
[
[0] "\n Johnny Mnemonic\n ",
[1] "\n Constantine\n "
]
との唯一の本当の違いは、search
のようなものです。at
at
search(...).first
「スクレイピング時にノードからのすべてのテキストを結合しないようにする方法」も参照してください。
Nokogiriには、便宜上、いくつかの追加のエイリアスがあります:およびat_css
、、css
および。at_xpath
xpath
Pryから切り取った、CSSおよびXPathアクセサーを使用して名前を取得する別の方法を次に示します。
[5] (pry) main: 0> # using CSS with Ruby
[6] (pry) main: 0> artists = doc.search('release').map{ |release| release.at('artist').text.strip }
[
[0] "Johnny Mnemonic",
[1] "Speed"
]
[7] (pry) main: 0> # using CSS with less Ruby
[8] (pry) main: 0> artists = doc.search('release artists artist:nth-child(1) name').map{ |n| n.text }
[
[0] "Johnny Mnemonic",
[1] "Speed"
]
[9] (pry) main: 0>
[10] (pry) main: 0> # using XPath
[11] (pry) main: 0> artists = doc.search('release/artists/artist[1]/name').map{ |t| t.content }
[
[0] "Johnny Mnemonic",
[1] "Speed"
]
[12] (pry) main: 0> # using more XPath
[13] (pry) main: 0> artists = doc.search('release/artists/artist[1]/name/text()').map{ |t| t.content }
[
[0] "Johnny Mnemonic",
[1] "Speed"
]