備忘録ですが何かの役に立てればと思って公開します。DOM の切り貼りがメインです。Nokogiri でスクレイピングができる人が対象です。スクレイピングに使いたい人はぐぐればたくさん例が出てくるのでこんな読みづらいメモを読んで時間を無駄にすることはないと思います
備忘録ですので随時内容の修正、追加をおこないます。
準備
bundler
を使って nokogiri
のインストールをするというよくあるやつです。
- 適当なディレクトリを作って移動
- 必要なら rbenv とかで ruby のバージョンをどうのとかやる
-
$ bundle init
で Gemfile を生成 - Gemfile 末尾に
gem "nokogiri"
の行を付け加える $ bundle install --path=.bundle/vendor/bundle
ここまでで Nokogiri
がインストールされ使えるようになりました。続いて初期のコードです。
#!/usr/bin/env ruby
require 'bundler'
Bundler.setup(:default, :ci)
require 'nokogiri'
RAW_HTML = DATA.read # __END__ の次行から末尾まで読み込む
def get_document
Nokogiri::HTML(RAW_HTML, nil, 'utf-8')
end
__END__
<html>
<head>
<title>hello</title>
</head>
<body>
<p>hello</p>
<p id="foo">goto <a href="https://qiita.com">Qiita</a> site!</p>
</body>
</html>
以後この get_document で Nokogiri::HTML::Document
を生成してからコード例を挙げていきます。いちいち生成し直すのは紹介するメソッドの殆どが破壊的メソッドだからです。なおコード例は __END__
の前に記述してください。
例題
内容の変更
doc = get_document
doc.at_css('title').content = 'new title'
puts doc.at_css('title') # => '<title>new title</title>'
# #foo の子供の最初のノード (goto ) を書き換える
doc.at_css('#foo').children[0].content = 'this is '
puts doc.at_css('#foo') # => '<p id="foo">this is <a href="https://qiita.com">Qiita</a> site!</p>'
ただし Nokogiri::XML::Text#content=
にタグつきの文字列を渡してもエスケープされてしまいます。
メソッド css
と at_css
の違いについて
スクレイピング方面の話題ですが、よく忘れるので。ノード (要素) を CSS セレクタで特定する二種類のメソッドがあります1。
doc = get_document
p doc.css('p').map{|x| x.to_s} # => ["<p>hello</p>", "<p id=\"foo\">goto <a href=\"https://qiita.com\">Qiita</a> site!</p>"]
puts doc.at_css('p').to_s # => <p>hello</p>
要は
-
Nokogiri::XML::Searchable#css
は条件に合致する要素をすべてリストアップする -
Nokogiri::XML::Searchable#at_css
は条件に合致した最初の要素を返す
ということです。id
属性で取り出すときなんかはドキュメント中にひとつしかないので at_css
で取るとよいかと思います。
特定要素の内容をごっそり入れ替える
doc = get_document
doc.at_css('#foo').children.unlink
doc.at_css('#foo') << '<span>new text</span>'
puts doc.at_css('#foo') # => '<p id="foo"><span>new text</span></p>'
こちらはタグが使えます。ちなみに Nokogiri::Node#<<
メソッドは要素の内容の末尾に付け加えるものです。なので最初の行の 〜.children.unlink
がなければ、「site!」の後ろに span
要素が挿入されることになります。やってみるとわかると思います。
参考文献
- Module: Nokogiri 多分ここが一次資料です
-
xpath で指定する方法もあるようですがが使ったことがありません。 ↩