LoginSignup
28
23

More than 5 years have passed since last update.

Nightmareで郵便局から住所をスクレイピング

Last updated at Posted at 2015-10-20

目的

郵便局のサイトでは http://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=100-0001 といったURLで、郵便番号から住所を引くことができます。
ただ何かしらの自動処理に組みこもうとすると、APIは提供されておらず、更新あるたびにCSVダウンロードするのも面倒なので、スクレイピングしてみました。(zipcloudなどの外部API化サービスには後で気づきました……)

※郵便局のサイトは、robots.txt利用規約を見るかぎり自動アクセスを禁止していないようです。アクセス頻度は常識的な範囲にとどめてください。

Nightmare

Nightmare(v2)は、Electronベースのブラウジング自動化ライブラリです。
今回はページ取得だけに使う……のは寂しいので、 http://www.post.japanpost.jp/zipcode/index.html の検索フォームからわざわざページ遷移してみます(ぉぃ

HTML

本記事投稿時点では、class="data"で引っかけると住所のテキストが見つかります。

<tr>
  <td class="data"><small>100-0001</small></td>
  <td class="data"><small>東京都</small></td>
  <td class="data"><small>千代田区</small></td>
  <td>
  <div class="data">
    <p><small><a href="zipcode.php?pref=13&city=1131010&id=46366&merge=">千代田</a></small></p>
    <p class="comment"><small>チヨダ</small></p>
  </div>
</td>

コード

Nightmare公式の実行例では非同期制御のため、coに似たvoというライブラリを使っていますが、ここでは標準のPromise.resolvePromise化してみました。
APIドキュメントには書いてないですが、Nightmareはthenというメソッド持っているので、Thenableっぽいです。また、coやvoでもyield構文で使えるので、Yieldableでもあるみたい。

main.js
'use strict';

var Nightmare = require('nightmare');
var nightmare = Nightmare();

Promise.resolve(
  nightmare.
    goto('http://www.post.japanpost.jp/zipcode/index.html').
    type('input[name="zip"]', process.argv[2]).
    click('input[src="/img/zipcode/btn_add_search_s.gif"]').
    wait('.data').
    evaluate(() => {
      var data = document.getElementsByClassName('data');
      return {
        zip:  data[0].innerText,
        pref: data[1].innerText,
        city: data[2].innerText,
        aza:  data[3].children[0].innerText
      };
    }
  )
).
  then((address) => {
    console.log('' + address.zip + ' ' + address.pref + address.city + address.aza);
  }).
  catch(console.error);

nightmare.end();

直感的にメソッドチェーンできて良いですね><b
きちんとセレクタで掴めているか確かめる際は、Nightmare({fullscreen: true});として適当にwait()挟んでおくと、ブラウジングの様子が見れて便利です。

実行結果

> node main.js 1000001

〒100-0001 東京都千代田区千代田

yieldとかPromise使っているので、node環境によっては--harmonyオプション必要かも。

環境

pacakge.json
{
  "dependencies": {
    "nightmare": "^2.0.7"
  }
}
> node -v
v4.2.1
28
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
23