東京に棲む日々

データ分析、統計、ITを勉強中。未だ世に出ず。

Rubyによるスクレイピング 練習1

Webからいろんなデータを取ってきたいなと思い、Rubyスクレイピングを練習中。

 

 損保ジャパン総研のページの”米国保険用語の解説”全ページの用語を取ってきて2列のデータに構造化する練習プログラム。

 

クローリングを行いすべてのHTMLをローカルに落としてくる。

 

 net/httpライブラリに関して。

http://magazine.rubyist.net/?0013-BundledLibraries

 

kconvライブラリに関して。

http://magazine.rubyist.net/?0009-BundledLibraries

require 'kconv'    	# エンコード処理ライブラリ
require 'net/http'	# HTTP用ライブラリ
Net::HTTP.version_1_2

# 配列の中すべてのページを処理
page = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","r","s","t","u","v","w"]

# ハッシュでデータを管理
data1 = {}

# ページの取得
page.each do |p|
  Net::HTTP.start("www.sj-ri.co.jp", 80) { |http|
  
    response = http.get("/glossary/#{p}.html")

    # 保存するデータはSJISに指定
    data1[p] = response.body.tosjis
  }
end

# ファイルの作成と書き込み関数
def save_html(key, dt)
  path = "html_raw/"
  file_name = "terms_#{key}.html"
  path_file_name = path + file_name
  
  # ファイルを作成し、内容を書き込む
  File.open(path_file_name, 'w') do |f|
    f.write(dt)
  end
end

data1.each do |key, value|
  save_html(key, value)
end

事前にディレクトリ上に"html_raw" フォルダを作成しておく。

実行するとフォルダの中に22個のHTMLファイルが作成される。

 f:id:High_School_Student:20140327181030j:plain

 
プロキシサーバ経由でアクセスする場合は、プロキシ情報を加え、ページの取得部分を以下に変更。

# プロキシ情報
proxy_host = 'my.proxy.host'
proxy_port = 8080
proxy_user = "username"
proxy_pass = "password"

# ページの取得
page.each do |p|

  # プロキシ経由でアクセス
  Net::HTTP.Proxy(proxy_host, proxy_port, proxy_user, proxy_pass).start("www.sj-ri.co.jp", 80) { |http|
    response = http.get("/glossary/#{p}.html")

    # 保存するデータはSJISに指定
    data1[p] = response.body.tosjis
  }
end

 

 

HTMLファイルから必要箇所を取って構造化する。

 

nokogiriライブラリを使いHTMLから特定の要素を取り出す。

nokogiriライブラリは標準ライブラリではないので、事前にインストールしておく必要がある。

nokogiriの使い方に関しては以下ページを参考。
http://morizyun.github.io/blog/ruby-nokogiri-scraping-tutorial/
http://www.engineyard.co.jp/blog/2012/getting-started-with-nokogiri/

 

require 'csv'
require 'nokogiri'

path_in = "html_raw/"

page = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","r","s","t","u","v","w"]

# 用語のタイトルを格納する配列
ttl = [ ]
# 用語を格納する配列
txt = [ ]

# 1ページづつ処理
page.each do |p|
  file = path_in + "terms_#{p}.html"
  html = File.read(file)
  doc = Nokogiri::HTML(html)

  # タイトルを取得
  doc.xpath('//td/h1').each do |node|
    ttl << node.text
  end

  # 用語を取得
  i = 0
  doc.xpath('//td/p[@class="m"]').each do |node|
    txt << node.text if i>0
    i += 1
  end
end

# csvにタイトルと用語の2列のデータを保存
CSV.open("final.csv", 'w') do |csv|
  ttl.length.times do |i|
    csv << [ttl[i],txt[i]]
  end
end

 

ディレクトリ上に"final.csv"が作成される。

 f:id:High_School_Student:20140329085645j:plain