10
9

More than 3 years have passed since last update.

郵便番号で住所情報を返却するAPIをNode.jsで簡単構築

Last updated at Posted at 2017-08-05

概要

よくある郵便番号に対して住所情報を返却するAPIをNode.jsで構築しました。
①定期的に日本郵便のサイトから住所情報をダウンロードし、SQLiteに登録
②郵便番号を受け取り住所情報をSQLiteから取得し返却するAPIをNode.jsで構築

環境

・CentOS
・Node.js
・SQLite
※Vagrantにて仮想環境構築

事前準備

npm

日本郵便のデータ読込(shift-jis)

npm install icov-lite

ダウンロードしたZIP解凍用

npm install unzip

Node.jsでsqlite操作するためにインストール(※)

npm install sqlite3

※手元の環境だとエラーになったため、Gitから直接インストールしました。

npm install https://github.com/mapbox/node-sqlite3/tarball/master

SQLite

yumコマンドでSQLiteをインストール

yum -y sqlite

DBを作成

sqlite3 ZipInfo.db

住所情報を登録するためのテーブル作成

CREATE TABLE zipinfotbl (
  allLocalCode varchar(128)
  ,oldZipCode varchar(128)
  ,zipCode varchar(128)
  ,prefectureKana varchar(128)
  ,townKana varchar(128)
  ,localKana varchar(128)
  ,prefectureName varchar(128)
  ,townName varchar(128)
  ,localName varchar(128)
  ,IsMultiLocalOneZipCode varchar(1)
  ,IncludeSmallChar varchar(1)
  ,IncludeChome varchar(1)
  ,IsZipDuplication varchar(1)
  ,IsUpdate varchar(1)
  ,ChangeKbn varchar(1)
  );

ソース

WriteZipDB.js
var http = require('http');
var unzip = require('unzip');
var fs = require('fs');
var iconv = require('iconv-lite');
var readline = require('readline');
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('ZipInfo.db');

var ZIP_FILE  = "KEN_ALL.zip";
var CSV_FILE = "KEN_ALL.csv";


function downloadZIPCSV(){
    // 日本郵便の住所情報データURL
    var downloadUrl = 'http://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip';

    // ダウンロードしZIPを解凍
    var outFile = fs.createWriteStream(ZIP_FILE);
    var rss = ''; 
    var req = http.get(downloadUrl, function (res) {

         res.pipe(outFile);
         res.on('end', function () {
            outFile.close();

            fs.createReadStream(ZIP_FILE).pipe(unzip.Extract({ path: './' }));
         }); 
    });
}

function writeDB(){
    // CSVファイルを1行ずつ読込
    var kenALLCSVFS = fs.createReadStream('KEN_ALL.CSV').pipe(iconv.decodeStream('shift_jis'));
    var kenALLCSVRL = readline.createInterface({'input': kenALLCSVFS, 'output': {}});
    kenALLCSVRL
    .on('line', function(line){
        // 読み込んだ行情報を配列化しDBに登録
        var csvdata = line.replace(/\"/g,"").split(",");
        insert(csvdata);
    })
}

var insert = function (param){
  db.serialize(function () {

    db.run('insert or replace into zipinfotbl'
     +' (allLocalCode,oldZipCode,zipCode,prefectureKana,townKana,localKana,prefectureName,townName,localName,IsMultiLocalOneZipCode,IncludeSmallChar,IncludeChome,IsZipDuplication,IsUpdate,ChangeKbn) '
     +' values ($allLocalCode,$oldZipCode,$zipCode,$prefectureKana,$townKana,$localKana,$prefectureName,$townName,$localName,$IsMultiLocalOneZipCode,$IncludeSmallChar,$IncludeChome,$IsZipDuplication,$IsUpdate,$ChangeKbn)', 
      {
        $allLocalCode : param[0],
        $oldZipCode : param[1],
        $zipCode : param[2],
        $prefectureKana : param[3],
        $townKana : param[4],
        $localKana : param[5],
        $prefectureName : param[6],
        $townName : param[7],
        $localName : param[8],
        $IsMultiLocalOneZipCode : param[9],
        $IncludeSmallChar : param[10],
        $IncludeChome : param[11],
        $IsZipDuplication : param[12],
        $IsUpdate : param[13],
        $ChangeKbn : param[14]
      }
    );
  });
};


// 日本郵便からZIPファイルをダウンロードしCSVとして解凍
downloadZIPCSV();
// SQLiteに書き込み
writeDB();

GetZipInfoAPI.js
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('ZipInfo.db');
var http = require('http');
var url = require('url');
var port = "3000";

function GetZipInfoAPI(zipCode, callback){
    db.all("SELECT * FROM zipinfotbl where zipCode = ?",[zipCode], function(err, rows){
      if (!err) {
          callback(rows[0]);
      }else{
          callback(null);
      }
    }); 
}


http.createServer(function (req, res) {
    res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });

    var url_param = url.parse(req.url,true);
    var zipCode = url_param.query.zipCode;
    console.log(zipCode);
    if(zipCode == null || zipCode == undefined){
        res.write('RequiredParam : zipCode');
        res.end(); 
        return;
    }

    // 住所情報取得
    var zipinfodata = GetZipInfoAPI(zipCode, function(row){
        if(row == null){
            res.write('No Data...');
            res.end(); 
        }else{
            res.write('{ '
                + ' "adr1" : "' + row.prefectureName + '"'
                + ' "adr2" : "' + row.townName + '"'
                + ' "adr3" : "' + row.localName + '"'
                + ' "adrK1" : "' + row.prefectureKana + '"'
                + ' "adrK2" : "' + row.townKana + '"'
                + ' "adrK3" : "' + row.localKana + '"'
                + '}');
            res.end();
        }
    });



}).listen(port);

利用方法

住所情報を日本郵便からダウンロード

node WriteZipDB.js

ダウンロード〜DB登録まで約10分ぐらい掛かります。
パフォーマンスもっと良い方法があるとは思いますが簡易版ということでご勘弁を…

定期実行の間隔としては一週間に一度実施する程度のcron設定で十分かと思います。

API起動

node GetZipInfoAPI.js

サンプルソースではポート3000を利用してます。
アクセスしてみて住所情報が取得出来ればOK.
スクリーンショット 2017-08-06 3.48.16.png

10
9
2

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
10
9