Rubyと筋肉とギターとわたし

筋トレが仕事です

【Ruby】スクレイピングをするときはUserAgentを設定しましょう

どうもてぃです。

現在業務でスクレイピングをしたデータをシステム上でよしなにやって、楽しく過ごしています。

今回とある、巨大なECサイト(俗称:熱帯雨林)をスクレイピングした際にエラーに見舞われたので、解決策を残しておこうと思います。

実行環境

つかったもの

Rubyスクレイピングといえばnokogiriですよね。

もちろん、今回もこの子を使いました。

何が起こったか

以下がソース。

一般的な使い方ですね。

require 'open-uri'
require 'nokogiri'

sufixes = [1, 2, 3, 4]
sufixes.each do |sufix|
  url = Constants::BASE_URL + suffix
  charset = nil

  begin
    html = open(url) do |f|
      charset = f.charset
      f.read
    end
  rescue => e
    puts e
    next
  end

  doc = Nokogiri::HTML.parse(html, nil, charset)
 ・
 ・
 ・
end

上記の書き方だと、スクレイピング先が多くなればなるほど、一定確率で 503エラーが発生します。

これは、スクレイピングするURLをopenするときに、ユーザーエージェントが指定していないため発生するそう。

なので、擬似的にユーザーエージェントを指定してあげる。

解決方法

開発者コンソールを開いて、Network -> ctrl + rで更新 -> bookmarkのファイルを選択 -> RequestHeaderのユーザーエージェントをコピーして適当に使う。

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/xxxxxx (KHTML, like Gecko) Chrome/xxxxxx Safari/xxxxx

こんな感じのやつ。

これでなくても、ユーザーエージェントを偽装してやればいいので、正直言えばなんでもいい。

require 'open-uri'
require 'nokogiri'

opt = {}
opt['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/xxxxxx (KHTML, like Gecko) Chrome/xxxxxx Safari/xxxxx'

sufixes = [1, 2, 3, 4]
sufixes.each do |sufix|
  url = Constants::BASE_URL + suffix
  charset = nil

  begin
    # open時にぶち込む
    html = open(url, opt) do |f|
      charset = f.charset
      f.read
    end
  rescue => e
    puts e
    next
  end

  doc = Nokogiri::HTML.parse(html, nil, charset)
 ・
 ・
 ・
end

こうすると、503エラーでスクレイピング失敗することがなくなります。

nokogiriでこんなエラー出たの初めてだったので結構困りました。

解決できてよかった。