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

node-csv-parserで郵便番号処理(spwanで直接iconv)

More than 5 years have passed since last update.

日本郵便のcsv ( http://www.post.japanpost.jp/zipcode/download.html ) をデータベースへ突っ込んで利用するというのは昔なつかしの『入門Ajax』で書いたことがありますが、最近はNode.jsのCSVパーサーでいきなり利用するってこともできることに気づきました。

てことで、試してみます。

パッケージは、node-csv-parser
https://github.com/wdavidw/node-csv-parser

インストール

npm install csv

文字コードをどうするぅ?

日本郵便のcsvは、Shift_JISなのでutf-8へ直してやる必要があるんだけれど、node-iconvはまだ今一つで、実際に試してみるとやっぱりだめでした。

そこで、チャイルドプロセスのexecかspwanで直接iconvやnkfを使ってファイルのコード変換やろうってことで試したらうまくいきましたのでこれでいきます。

var csv = require('csv');
var exec = require('child_process').exec;

var zip = '3001626';//調べたい郵便番号

//入出力ファイル 08IBARAK.CSVから08IBARAK-utf8.CSVを作る
var infile = __dirname+'/08IBARAK.CSV';
var outfile = __dirname+'/08IBARAK-utf8.CSV';

//iconvコマンド
var cmd = 'iconv -f SHIFT_JIS -t UTF-8 -o '+outfile+' '+infile+'';

//文字コード変換 入力ファイルをUTF-8へ変換して出力後CSV処理起動
var child = exec(cmd,
  function (error, stdout, stderr) {
    getCSV();//CSV処理起動
    if (error !== null) {
      console.log('exec error: ' + error);
    }
});

//CSV処理
function getCSV(){
  console.time('bench');
  csv()
    .fromPath(outfile) //読み込むCSVファイル
    .transform(function(data){//絞り込みと変換加工処理
      if(data[2]===zip){
        data[8]=
          data[8]
            .replace('以下に掲載がない場合','')
            .replace('境町の次に番地がくる場合','')
        return data[2]+ ' ' +data[6] +data[7] +data[8];
      }
    })
    .on('data',function(data){
      console.log(data);//変換後のデータを受け取り表示
      console.timeEnd('bench');
    })
    .on('end',function(count){
        console.log('Number of lines: '+count);
    })
    .on('error',function(error){
        console.log(error.message);
    }) 
}

こうなった

$ node app.js

3001626 茨城県北相馬郡利根町四季の丘
Number of lines: 2856

速度はこの3000件で0.2秒かかってるので、文字コード部分は別処理にすべきかも。

まぁ、DBへ流し込む前のCSVパーサーとして使うのが普通かもしれないけれど、単体でもこんな風に絞り込みにも使えるわけなので、速度を気にしなければ日本郵便のデータ更新への対応のハードルが下がるというメリットもあるかも?

P.S. KEN_ALL.CSVの12万3千件の最後の沖縄の郵便番号9071801を検索したら、9166msだったので、まぁ、数万件ある場合は、やはり実用上はDBへ流し込んで使うべきですね(^^;;

P.S. ちなみに、文字コード変換後のファイルを作らずに、getCSV(stdout);で渡す手もあった。ただし、データが大きくなるとError: maxBuffer exceeded.となるので、たとえば、次のようにmaxBufferを大きくしてみた。

var cmd = 'iconv -f SHIFT_JIS -t UTF-8 '+infile+''
//入力ファイルをUTF-8へ変換して出力後CSV処理起動
var child = exec(cmd,{
    maxBuffer: 20000*1024
  },
  function (error, stdout, stderr) {  
    console.log('stderr: ' + stderr);
     getCSV(stdout);//CSV処理起動
toshirot
JavaScriptの周辺でうろうろしてます。 著作リスト http://www.amazon.co.jp/-/e/B004LRDBIG
https://twitter.com/toshirot
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
ユーザーは見つかりませんでした