地域データの構造化テキストを公開しました。
はじめに
読み仮名データの促音・拗音を小書きで表記するもの - zip圧縮形式 日本郵便
駅データ 無料ダウンロード 『駅データ.jp』
最近は専らデータの整形屋になっている@yutakikucです。今日は日本郵便株式会社と駅データ.jpに掲載されているデータを利用して、地域データを構造化テキストとして作成します。ここでの目的は上のリンクで公開されている地域データの形式がCSVだったり、WebAPIのXMLだったり、データが1箇所にまとめられていなかったりと少し不便を感じたので構造化テキストを作成することにしました。出力形式は名前ベースのYAMLです。尚、下で公開したデータの利用は全て自己責任でお願い致します。
PyYAMLの利用
YAML形式をGenerateする言語はpythonを利用します。pythonのYAMLライブラリのPyYAMLを使うのでその設定方法を書いておきます。import yamlが実行出来れば設定が完了しています。
$ wget "http://pyyaml.org/download/pyyaml/PyYAML-3.10.zip" $ unzip PyYAML-3.10.zip $ cd PyYAML-3.10 $ sudo python setup.py install $ python Python 2.6.6 (r266:84292, Sep 11 2012, 08:34:23) [GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import yaml >>>
地域名データ/郵便番号のYAML化
県名、市区町村のデータの冗長化を防ぐためにYAMLのkeyとして設定しデータに重複が発生しないようにしています。以下が簡単なDataFormatとSampleDataです。日本郵便のサイトからDataをDownloadしてYAMLファイルを生成するのを下のPythonで自動的にやってくれますが、僕が試しに実行してみたところ処理に5分程掛かってしまい少し重たく感じます。生成したファイルをGithubに上げました。
Github
- Data/zipcode.yaml at master · yutakikuchi/Data · GitHub
- Fileサイズが大きくてGithubのWebViewでは見ることが出来ません。
$ git clone git@github.com:yutakikuchi/Data.gitDataFormat/SampleData
県名: 市名: 町村名: city_kana:市名のカナ表記 prefecture_kana:県名のカナ表記 town_kana:町村名のカナ表記 zipcode:郵便番号新潟県: 三島郡出雲崎町: 上中条: city_kana: サントウグンイズモザキマチ prefecture_kana: ニイガタケン town_kana: カミナカジョウ zipcode: '9494341' 上野山: city_kana: サントウグンイズモザキマチ prefecture_kana: ニイガタケン town_kana: ウエノヤマ zipcode: '9494346' 中山: city_kana: サントウグンイズモザキマチ prefecture_kana: ニイガタケン town_kana: ナカヤマ zipcode: '9494345' 久田: city_kana: サントウグンイズモザキマチ prefecture_kana: ニイガタケン town_kana: クッタ zipcode: '9494301'generate YAML
#!/usr/bin/env python # -*- coding: utf-8 -*- # 地域情報のYAML化 import sys,re,urllib,zipfile,os,yaml zip_url = 'http://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip'; urllib.urlretrieve( zip_url, './ken_all.zip' ) zf = zipfile.ZipFile( './ken_all.zip', 'r' ) dict_data = {} non_string = u'以下に掲載がない場合' for f in zf.namelist(): if not os.path.basename(f): break else: try: data = open( f, 'r' ) for line in data: try: line = line.decode( 'cp932' ).replace( '"', '' ) nodes = line.split(',') zipcode = nodes[2] if nodes[2] is not None and nodes[2] != '' and nodes[2] != non_string else 'N/A' prefecture_kana = nodes[3] if nodes[3] is not None and nodes[3] != '' and nodes[3] != non_string else 'N/A' city_kana = nodes[4] if nodes[4] is not None and nodes[4] != '' and nodes[4] != non_string else 'N/A' town_kana = nodes[5] if nodes[5] is not None and nodes[5] != '' and nodes[5] != non_string else 'N/A' prefecture = nodes[6] if nodes[6] is not None and nodes[6] != '' and nodes[6] != non_string else 'N/A' city = nodes[7] if nodes[7] is not None and nodes[7] != '' and nodes[7] != non_string else 'N/A' town = nodes[8] if nodes[8] is not None and nodes[8] != '' and nodes[8] != non_string else 'N/A' dict_data.setdefault( prefecture, {} ).setdefault( city, {} ).setdefault( town, {} ) dict_data[prefecture][city][town]['zipcode'] = zipcode.encode( 'utf-8' ) dict_data[prefecture][city][town]['prefecture_kana'] = prefecture_kana dict_data[prefecture][city][town]['city_kana'] = city_kana dict_data[prefecture][city][town]['town_kana'] = town_kana except UnicodeEncodeError: continue except Exception, e: print str(e) continue savefile = open( 'zipcode.yaml', 'w' ) yaml.dump( dict_data, savefile, default_flow_style=False, encoding='utf8', allow_unicode=True )$ python zipcode.py
駅データのYAML化
利用規約 | 駅データ 無料ダウンロード 『駅データ.jp』
CodePlus さんが提供している駅データ.jpですが、利用規約に書かれている第4条 (利用)/第5条 (加工)/第6条 (第三者提供)の項目が利用者フレンドリーで素晴らしく思います。敬意を表したいと思います。こちらも生成したYAMLファイルをGithubに上げました。Github
- Data/transit.yaml at master · yutakikuchi/Data · GitHub
- RawData/transit.yaml at master · yutakikuchi/Data · GitHub
$ git clone git@github.com:yutakikuchi/Data.gitDataFormat/SampleData
県名: 路線名: 駅名: station_code:駅名コード station_lat:駅の緯度 station_lon:駅の経度新潟県: JR上越線: 上牧: station_code: 1134213 station_lat: 36.735616 station_lon: 138.984533 上越国際スキー場前: station_code: 1134223 station_lat: 37.028754999999997 station_lon: 138.82797299999999 五日町: station_code: 1134226 station_lat: 37.119900000000001 station_lon: 138.90834599999999 井野: station_code: 1134203 station_lat: 36.357456999999997 station_lon: 139.023247generate YAML
#!/usr/bin/env python # -*- coding: utf-8 -*- # 地域情報のYAML化 # transit.pyとして保存する import time,urllib,urllib2,zipfile,os,yaml,xml.dom.minidom base_url = 'http://www.ekidata.jp/api/' base_pref_url = base_url + 'p/' base_line_url = base_url + 'l/' opener = urllib2.build_opener() ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.51.22 (KHTML, like Gecko) Version/5.1.1 Safari/ 534.51.22' referer = 'http://www.ekidata.jp/' opener.addheaders = [( 'User-Agent', ua ),( 'Referer', referer )] dict_data = {} for i in range(1,48): pref_url = base_pref_url + str( i ) + '.xml' try: pref_content = opener.open( pref_url ).read() pref_dom = xml.dom.minidom.parseString( pref_content ) pref = pref_dom.getElementsByTagName( 'pref' )[0] pref_code = pref.getElementsByTagName( 'code' )[0].firstChild.data pref_name = pref.getElementsByTagName( 'name' )[0].firstChild.data lines = pref_dom.getElementsByTagName( 'line' ) for line_data in lines: try: time.sleep(0.5) line_code = line_data.getElementsByTagName( 'line_cd' )[0].firstChild.data line_name = line_data.getElementsByTagName( 'line_name' )[0].firstChild.data line_url = base_line_url + str( line_code ) + '.xml' line_content = opener.open( line_url ).read() line_dom = xml.dom.minidom.parseString( line_content ) stations = line_dom.getElementsByTagName( 'station' ) for station in stations: station_code = station.getElementsByTagName( 'station_cd' )[0].firstChild.data station_name = station.getElementsByTagName( 'station_name' )[0].firstChild.data station_lat = station.getElementsByTagName( 'lat' )[0].firstChild.data station_lon = station.getElementsByTagName( 'lon' )[0].firstChild.data dict_data.setdefault( pref_name, {} ).setdefault( line_name, {} ).setdefault( station_name, {} ) dict_data[pref_name][line_name][station_name][ 'station_code' ] = int( station_code.encode( 'utf-8' ) ) dict_data[pref_name][line_name][station_name][ 'station_lat' ] = float( station_lat.encode( 'utf-8' ) ) dict_data[pref_name][line_name][station_name][ 'station_lon' ] = float( station_lon.encode( 'utf-8' ) ) except Exception, e: print str(e) continue except Exception, e: print str(e) continue savefile = open( 'transit.yaml', 'w' ) yaml.dump( dict_data, savefile, default_flow_style=False, encoding='utf8', allow_unicode=True )$ python transit.py