Help us understand the problem. What is going on with this article?

日本酒が美味しい県へ旅行に行くために~スクレイピングとD3.jsによる可視化(その1)~

More than 3 years have passed since last update.

動機

1.日本酒が美味しい所に旅行行きたい!(できれば海の日3連休に)
2.スクレイピングの勉強会に参加して、わくわくしたのでやってみたい
3.D3.jsに以前から興味があった

処理概要

  1. スクレイピングでデータ取得
  2. データ加工
  3. D3.jsで日本地図描画           ( ←今回ここまで )
  4. 描画した日本地図にスクレイピングでとってきたデータを反映
  5. 結果を見て目的地を決めて旅行に行って美味しい日本酒を飲んでくる

※可視化はすでにやっている方がいらっしゃいました。素晴らしい。。
http://gonomee.com/topics/alpha_ranking/

スクレイピングとは

※混同されがちな言葉にクローリングがある

  • クローリング・・・リンクを辿ってWebページを収集すること
  • スクレイピング・・・収集したWebページから必要な情報を抜き出すことを指す(両者を区別せず使うことも多いらしい)

スクレイピングを行う上での注意点

  • スクレイピングしたデータの使用目的や方法によっては、情報公開元に迷惑をかけたり、場合によっては法に触れることもある
  • 以下のページを読み誰にも迷惑をかけないWebスクレイピングを心がけるべし

  • APIが提供されている場合はそちらを利用する

  • サイトの利用規約を確認する

  • robots.txtを確認する

    • 大体のサイトに用意されているらしい。取得したいサイトのトップページのURLの末尾にrobots.txtをつけて確認
  • Webサイトに負荷をかけないようにアクセスする

    • sleepを入れて行うらしい←未学習

スクレイピングの大まかな手順

  1. スクレイピングを行いたいページを取得する
  2. ページのDOMツリーを確認する
  3. 欲しいデータを抽出する

今回は「日本酒 都道府県 ランキング」でぐぐってTOPに出てきた日本酒ランキングのページを取得してきたいと思います。
(http://www.sakeno.com/ranking/)

scraping.py
# -*- coding:utf-8 -*-
import pandas as pd
import requests
from bs4 import BeautifulSoup
import re

#抽出してきたタグを含む文字列から必要な単語のみをとってくる関数
def str_select(tag_name):
    str_list = []
    for name in tag_name:
        str_list.append('{name}'.format(name=name.string))
    return str_list

#WEBページのHTMLをgetし、ファイルとして保存
res = requests.get('http://www.sakeno.com/ranking/') #Response オブジェクト
with open('nihonsyu_ranking.html', 'wb') as f:
    f.write(res.content)

#WEBページの文字コードを確認して、encoding指定してHTMLを読み込む
html = open('nihonsyu_ranking.html',encoding='EUC-JP').read()
soup = BeautifulSoup(html, 'html.parser')

#欲しい情報が構成されているHTMLタグを指定して、データをとってくる
#銘柄名
meigara = soup.find_all("strong", attrs={"class":"lrg"})
#都道府県名
tmp_pref = soup.find_all("td", attrs={"class":"smll"})
pref = []
for row in tmp_pref:
    pref += row.find_all("a", attrs={"href":re.compile("http://www.sakeno.com/ranking_todou/")})

#とってきたタグを含む文字列から欲しい単語のみを抽出
meigara_list = str_select(meigara)
pref_list = str_select(pref)
rank_list = []
for i in range(1,len(meigara_list)+1):
    rank_list.append(i)

#結果をデータフレーム化
output = pd.DataFrame()
output["meigara"] = meigara_list
output["pref"] = pref_list
output["rank"] = rank_list

#出力
output.to_csv('meigara_pref_rank.csv', index=False)

取得したデータ

meigara pref rank
獺祭 山口県 1
十四代 山形県 2
醸し人九平次 愛知県 3
黒龍 福井県 4
田酒 青森県 5
久保田 新潟県 6
出羽桜 山形県 7
飛露喜 福島県 8
八海山 新潟県 9
鳳凰美田 栃木県 10
〆張鶴 新潟県 11
... ... ...
麒麟 新潟県 190
酒一筋 岡山県 191
不老泉 滋賀県 192
花泉 福島県 193
米鶴 山形県 194
吉乃川 新潟県 195
翠露 長野県 196
三井の寿 福岡県 197
おんな泣かせ 静岡県 198
五橋 山口県 199
越州 新潟県 200

データ加工

  • 都道府県毎に銘柄数をカウント ※データ量が少ないのでExcelで加工
state value
新潟県 20
福島県 16
山形県 15
広島県 11
秋田県 10
宮城県 9
静岡県 9
長野県 9
兵庫県 7
岩手県 6
石川県 6
茨城県 5
... ...
香川県 1
山梨県 1
神奈川県 1
千葉県 1
徳島県 1
奈良県 1

データの準備は整った。
次は可視化の準備に取り掛かります!

D3.jsとは

  • Data Driven Documentの略
  • JavaScriptライブラリ
  • HTMLや SVG,CSSを使ってデータに命を吹き込んでくれる
  • ブラウザ上で動かせる
  • とにかくおしゃれ

事例紹介

日本地図を描画する

japan_plot.html
<!DOCTYPE html>
    <html lang ="ja">
        <head>
        <meta charset="utf-8">
        <script type="text/javascript" src="d3.min.js"></script>
        <script type="text/javascript" src="topojson.min.js"></script>
    <style>![Invalid file type: text/html]()

        body { background-color:LightCyan;}
    </style>
    </head>
    <body>
    <div id='example'></div>
    <script src="japan_plot.js"></script>
</body>
</html>
japan_plot.js
    //svg要素の設定
    var width = 600,
    height = 500;

    //D3を使ってsvg要素を生成し、中身を追加していく
    var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

    var color = d3.scale.category20();

    // 地図描画の準備 
    // 投影法(メルカトル法)の設定。
    var mercator = d3.geo.mercator()
        .center([136.0,35.6])
        .translate([width/2, height/2])
        .scale(800);

    // geojsonからpath要素を作るための設定
    var geopath = d3.geo.path()
    .projection(mercator);

    // topojsonファイルの読み込み
    d3.json("japan_topojson.json", function(error, jp) {
        console.log(jp);

        // topojsonからgeojsonへの変換。
        var geoJp = topojson.feature(jp, jp.objects.ne_10m_admin_1_states_provinces);
        console.log(geoJp);

        svg.selectAll("path")
            .data(geoJp.features) // geojsonのすべての県の座標データを読み込む。
          .enter().append("path")
            .attr("class", function(d) { return d.id; })
            .attr("d", geopath) // geojsonからpath要素に変換する。
            .attr("fill", function(d){ return color(d.geometry.coordinates); }); // idがないので、各県の座標リストに基づいて色を変える。
    });

日本地図描画できた。
japan.png

今後

  • csvファイルを日本地図に反映する(そして旅行にいく)
  • クローリングして取得するデータを増やしてみる
  • 自分の好きな日本酒の味などをキーワードにして自分好みの日本酒MAPにする
  • D3.js使っていろいろ可視化してみる
  • amd more...

D3.jsを使った地図可視化の他の方法のご紹介

参考にさせて頂いたサイト

ありがとうございます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした