読者です 読者をやめる 読者になる 読者になる

ハイパーニートプログラマーへの道

頑張ったり頑張らなかったり

【Ruby】4Gifsの各ページをnokogiriでスクレイピング、GIFのURL取得

【Ruby】4gifsのRSS取得、gifのURLを取り出す - ハイパーニートプログラマーへの道

この記事ではRSSのdescriptionからgifのURLを取り出した・・・つもりが動かないものだぞ!?

どうやらそのURLと、実際の個別記事のgifのURLは違うようだ。

要はRSSで表示された時のサムネイル的な画像なのかな?
(や、tumblrに投稿した時に動かないようだ。tumblr側で容量を圧縮しすぎてるからなのかな? わからんですが)

とにかく各個別記事にアクセスしてゲットせねばなるまい。ということで

nokogiriインストール前の準備

OSX - Mac OS X Mavericksで”gem i nokogiri”失敗の解決方法 - Qiita

こちらを見ていただくのが良いかと。

いざインストール、だが・・・

$ gem install nokogiri
ERROR:  Error installing nokogiri:
    invalid gem: package is corrupt, exception while verifying: undefined method `size' for nil:NilClass (NoMethodError) in /Users/noriyo_tcp/.rvm/gems/ruby-2.1.4/cache/nokogiri-1.6.3.1.gem

どうしてもinvalid gem: package is corrupt, exception while verifying:が出る。必死にググると・・・。

ruby - Error install rubyracer with error "invalid gem: package is corrupt" - Stack Overflow

cache以下をリムーブして入れ直せと。

$ rm /Users/noriyo_tcp/.rvm/gems/ruby-2.1.4/cache/nokogiri-1.6.3.1.gem
$ gem install nokogiri

んー、とくにBundlerを使ってgemを入れてるわけでもないので、普通に$ gem install nokogiriとやってしまったが・・・。

Ruby - 【メモ】invalid gem: package is corrupt, exception while verifying:~が出たので。 - Qiita

一応Qiitaにも投稿しておきました。

やっと本題

4GIFs.comの個別ページをChromeで調べる。

f:id:noriyo_tcp:20141104212032p:plain

GIFの箇所のXPathをコピーしときます。

//*[@id="gsImageView"]/table/tbody/tr[1]/td[1]/img

まあこれ全部使うわけではないのですけど・・・。

そしてコード。

require "open-uri"
require "nokogiri"
require 'rss'

base_url = 'http://forgifs.com'
new_posts = Array.new()
charset = nil

rss = RSS::Parser.parse('http://forgifs.com/gallery/srss/7')
rss.items.each do |item|
  url = item.link
  html = open(url) do |f|
    charset = f.charset
    f.read
  end
  doc = Nokogiri::HTML.parse(html, nil, charset)
  doc.xpath('//*[@id="gsImageView"]').each do |node|
    # //*[@id="gsImageView"]/table/tbody/tr[1]/td[1]/img
    $src = base_url + node.css('img').attribute('src').value
  end

  new_post = [item.title, item.link, $src, '4gifs']
  new_posts << new_post
end

puts new_posts

node.css('img').attribute('src').valueで返ってくるのは/gallery/d/221529-2/Falls-chair-headshot.gifこの形なので、base_urlを頭にくっつけてやると。

うん・・・お恥ずかしながらグローバル変数とか「通らねえな?ああここに$をつけときゃいいのか?」的な感じでテキトーに使っているのがアレですが。

実行結果

$ ruby 4gifs_test.rb 
Falls-chair-headshot
http://forgifs.com/gallery/v/Funny/Falls-chair-headshot.gif.html
http://forgifs.com/gallery/d/221529-2/Falls-chair-headshot.gif
4gifs
Grouper-steals-fish
http://forgifs.com/gallery/v/Animals/Grouper-steals-fish.gif.html
http://forgifs.com/gallery/d/221527-2/Grouper-steals-fish.gif
4gifs
Personal-trainer-cat
http://forgifs.com/gallery/v/Cats/Personal-trainer-cat.gif.html
http://forgifs.com/gallery/d/221518-2/Personal-trainer-cat.gif
4gifs
Germaphobe-public-toilet
http://forgifs.com/gallery/v/Funny/Germaphobe-public-toilet.gif.html
http://forgifs.com/gallery/d/221516-2/Germaphobe-public-toilet.gif
4gifs
Office-webcam-chat
http://forgifs.com/gallery/v/Funny/Office-webcam-chat.gif.html
http://forgifs.com/gallery/d/221452-2/Office-webcam-chat.gif
4gifs
Box-cat-head
http://forgifs.com/gallery/v/Cats/Box-cat-head.gif.html
http://forgifs.com/gallery/d/221448-2/Box-cat-head.gif
4gifs
Dogs-carrying-box-costume
http://forgifs.com/gallery/v/Dogs/Dogs-carrying-box-costume.gif.html
http://forgifs.com/gallery/d/221430-2/Dogs-carrying-box-costume.gif
4gifs
(以下略)

ほぼ下の記事そのままにやりました。

参考記事:

Nokogiri を使った Rubyスクレイピング [初心者向けチュートリアル] - 酒と泪とRubyとRailsと