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

GIS奮闘記

現役GISエンジニアの技術紹介ブログ。主にPythonを使用。

Pythonでスクレイピングした結果をGoogleMapに反映してみた

本日はPythonスクレイピングした結果をGoogleMapに反映してみました。具体的に言いますと、スクレイピングした情報(緯度経度)の位置にGoogleMap上でマーカーを作成します。スクレイピングについては以下ご参照ください。
ウェブスクレイピング - Wikipedia
なんだか小難しく書いてありますが、Webサイトから情報を引っこ抜くくらいの認識で問題ないと思います。

まず、スクレイピングはBeautifulSoupを推しているサイトもけっこうあったのですが、lxmlを使用してみました。pip install lxmlか以下サイトからダウンロードをする必要があります。
https://pypi.python.org/pypi/lxml/2.3
その他必要なライブラリはインストールをお願いします。

対象のサイトは以下です。
神奈川県内の水道事業者一覧 - 神奈川県ホームページ
神奈川県の水道事業者の一覧からその場所の緯度経度を取得して、そこにGoogleMap上でマーカーを作成しようと思います(実はわたくし水道関係の仕事をしております)。

■sample.py

# -*- coding: utf-8 -*-
from lxml.html import parse
from urllib2 import urlopen
import geocoder
import json

def main():
    parsed = parse(urlopen('http://www.pref.kanagawa.jp/cnt/f1029/p70915.html'))
    doc = parsed.getroot()
    blog_node = doc.xpath('//div[@class="detail_free"]')[0]

    json_data = []
    for a in blog_node.xpath('descendant::a'):
        href = a.get("href")
        if href:
            lat,lng = geo(a.text)
            if lat: #緯度経度が取得できたもののみ
                json_data.append({
                                "name": a.text,
                                "lat": lat,
                                "lng": lng
                                })

    with open('data.json', 'w') as outfile:
        json.dump(json_data, outfile, indent=4, sort_keys=True)

def geo(name):
    Localname = name
    g = geocoder.google(Localname)
    return g.lat,g.lng

if __name__ == '__main__':
    main()

上記では対象のサイトから情報を取得し、JSONとして出力しています。
それでは出力したJSONを読み込みたいと思います。

■sample.js

var map;

function initialize() {
  var latlng = new google.maps.LatLng(35.383575, 139.344170);
  var options = {
    zoom: 10,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById("map_canvas"), options);
  map.setCenter(latlng);
}

function loadJson(){
  var json = [];
  $(function(){
    $.getJSON("data.json" , function(data) {
    json = data;
    });
  });

  //JSONの要素数分マーカーを作成
  for (i = 0; i < json.length; i++) {
    latlng = new google.maps.LatLng(json[i].lat,  json[i].lng);
    var marker = new google.maps.Marker({
        position: latlng, 
        map: map,
    });
  }
}

JSONの読み込みには$.getJSONを使用しました。なので、jqueryも必要になりますね。
最後にhtmlです。

■sample.html

<!DOCTYPE html "-//W3C//DTD XHTML 1.0 Strict//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <meta name="robots" content="noindex,nofollow,noarchive" />
    <title>GoogleMapsAPI Sample</title>
    <script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyBu5Wf66_X6xMaD8y1B3qdZ8gCQM5gUl70&sensor=false"
            type="text/javascript"></script>
    <script src="./js/sample.js" type="text/javascript"></script>
    <script src="./js/jquery-1.5.2.js" type="text/javascript" ></script>
  </head>
  <body onload="initialize()">
    <div id="map_canvas" style="width: 500px; height: 500px"></div>
    <form>
    <p>
    <input type="button" id="btn" value="マーカー作成" onclick="loadJson()" />
    </p>
    </form>
  </body>
</html>

マップとボタンを作って、ボタンを押したらマーカーが作成される作りにしてみました。さて、実際に動かしてみます。


f:id:sanvarie:20151206103235p:plain


まずはマップが表示されました。続いて「マーカー作成」ボタンを押してみたいと思います。


f:id:sanvarie:20151206103336p:plain


マーカーが作成されました!
拡大してみると、きちんと水道事業者の位置にマーカーが作成されています。いやーすごいですね。今後はこれをもっと動的に実行できるようにしてみたいですね。ジオコーディング、逆ジオコーディングをするサイトのような感じでしょうか。


f:id:sanvarie:20151206103444p:plain


以上、本日はPythonスクレイピングした結果をGoogleMapに反映でした。