Skip to content

RubyでWebスクレイピング

yowasou edited this page Aug 13, 2023 · 2 revisions

スクレイピング

_ウェブスクレイピング(英: Web scraping)とは、ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと。ウェブ・クローラー[1]あるいはウェブ・スパイダー[2]とも呼ばれる。 _ (https://ja.wikipedia.org/wiki/ウェブスクレイピング)

クローリング?スクレイピング?

個人的には以下のように使い分けている.

Webクローリング

取得したhtmlからハイパーリンクを抽出し、リンクするページを抽出する.

Webスクレイピング

取得したhtmlから欲しいデータを抽出する.

Yahoo!ニュースのトピックから記事の一覧を取得する

元ネタ http://morizyun.github.io/blog/ruby-nokogiri-scraping-tutorial/

ruby -v 
=> ruby 2.4.0dev
gem install nokogiri -v '1.6.8'
require "nokogiri"
require "open-uri"
require "awesome_print"

url = "http://news.yahoo.co.jp/topics"
html = open(url)
doc = Nokogiri::HTML.parse(html)
ap doc.css(".topicsMod > .list > ul > li > a").map{|r| {href: r["href"], text:r.text} }

Nokogiri がインストールできない場合

Cloud9

やってみる

Nokogiriはインストールでハマりかねないので、オンラインIDEのCloud9を使うことにします。 (Rubyスクリプトではなく、Railsアプリとなる)

簡単に試してみたところ、

  • Nokogiriのインストールが可能
  • bin以下のコマンドがローカル時とかわりなく実行可能である

コードなど

プロジェクトの作成

create_a_new

しばし待つ

cloud9

IDEが起動する

cloud9_1

Gemfileに以下を追記

gem "nokogiri"
gem "awesome_print"
gem "hashie"
gem 'pry-byebug'

cloud9_2

bin/bundle install する

bin/bundle install

cloud9_3

controllerを作成

bin/rails g controller topics index

app/controllers/topics_controller

def index
  require 'open-uri'
  url = "http://news.yahoo.co.jp/topics"
  html = open(url)
  doc = Nokogiri::HTML.parse(html)
  @result = doc.css(".topicsMod > .list > ul > li > a").select{|r|r.text != "もっと見る"}.map{|r| Hashie::Mash.new(url: r["href"], text:r.text) }
end

cloud9_4

View

app/views/topics/index.html.erb

<div id="contents">
  <% @result.each do |r| %>
    <li><a href="<%= r.url%>"><%= r.text %></a></li>
  <% end %>
</div>

routingの設定

condig/routes.rb

root "topics#index"

「Run Project」ボタンをクリック後、「Your code is running~」の後のURLをクリック

cloud9_3

bin/rails consoleも実行可能

個人的には、irbとかpryで↑のdocあたりまで実行しておいて、そこからブラウザのDevelopperConsoleを開いて対象のページのHTMLとにらめっこしながらあーでもないこーでもないとcssパスの指定方法を試行錯誤する感じ。 綺麗に削り落とせたら、selectでフィルタしたりmapで整形したりする。

気をつけること

Webスクレイピングの法律周りの話をしよう!

Clone this wiki locally