LoginSignup
4
5

More than 5 years have passed since last update.

複数のCSVをnode.jsでまとめてパースして一つにして出力する

Posted at

Googleさんのモバイルフレンドリーアップデートで検索順位の推移をWebmaster Toolsから日別で取得してきたんだけど、推移を見るためにvlookupをコピペしまくるのが面倒だったのでnode.jsの勉強もかねて実装。

実行方法
node convert.js output.csv // 出力先は指定しないとconvined.csvに

各csvにキー(この場合はdate)を付与してパース、読み込み終了をpromiseで取得してconbinedに収納されたjsonのリストをごにょごにょして、klist経由でアウトプットファイルに出力。

CSVファイルの入出力とタスク制御までできたのでPromiseの中身を書き換えれば、いろんな集計の下準備の雛形的に使える……といいな。

入力ファイルはGoogle Webmaster Toolsの"検索トラフィック">"検索クエリ"で日付を1日ずつにしてCSVにアウトプット。

文字コードはutf-8のままなので、エクセルで読み込むには文字コードをshift-jisに変換する必要あり。ファイルリストもコマンドラインで渡せるようにしようぜ…と思いつつ未実装。

package.json
{
  "devDependencies": {
    "csv-parse": "^0.1.1",
    "json2csv": "^2.2.1",
    "lodash": "^3.7.0"
  }
}
convert.js
(function() {
  "use strict";

  require('events').EventEmitter.prototype._maxListeners = 100;

  var fs = require('fs');
  var _ = require('lodash');
  var parse = require('csv-parse');
  var json2csv = require('json2csv');

  var conbined = [];

  var dist = process.argv[2] || "conbined.csv";
  var files = [
    {'file': './your-site-name_20150505T000000Z_TopSearchQueries_20150414-20150414.csv', 'date': '20140414'},
    {'file': './your-site-name_20150505T000000Z_TopSearchQueries_20150421-20150421.csv', 'date': '20140421'},
    {'file': './your-site-name_20150505T000000Z_TopSearchQueries_20150428-20150428.csv', 'date': '20140428'}
  ];

  var tasks = _.map(files, function(file) {
    // make tasks from list of files to parse csv
    return new Promise(function(resolve, reject) {

      var output = [];

      var parser = parse({}, function(err, data) {
        var fr = data.shift();
        data = _.map(data, function(arr) {
          return _.object(fr, arr);
        });
        output.push(data);
      });

      var s = fs.createReadStream(file.file);
      var p =  s.pipe(parser);
      p.on('end', function() {

        output = _.map(output[0], function(obj) {
          obj.date = file.date;
          return obj;
        });
        conbined.push(output);
        resolve();
      });
    });
  });

  Promise.all(tasks).then(function(x) {
    var klist = [];
    conbined = _.flatten(conbined);

    // use conbined and output to klist
    conbined = _.map(conbined, function(obj) {
      var date = obj.date;
      var ret = {};
      ret["検索キーワード"] = obj["検索キーワード"];
      ret["表示回数-"+date] = obj["表示回数"];
      ret["クリック数-"+date] = obj["クリック数"];
      ret["CTR-"+date] = obj["CTR"];
      ret["平均掲載順位-"+date] = obj["平均掲載順位"];
      return ret;
    });

    conbined = _.groupBy(conbined, function(obj){
      return obj["検索キーワード"];
    });

    _.each(conbined, function(word) {
      var ret = {};
      _.each(word, function(col) {
        ret = _.extend(ret,col);
      });
      klist.push(ret);
    });

    // output to csv
    var keys = _.keys(klist[0]);
    console.log(keys);
    json2csv({data: klist, fields: keys}, function(err, csv) {
      if(err) {
        console.error(err);
      }
      fs.writeFile(dist, csv);
    });
  });

})();
4
5
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
4
5