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

初めてのNode.js学習メモ

More than 3 years have passed since last update.

先日、Webクローラーと機械学習という言葉に惹かれて、「JS+Node.jsによるWebクローラー/ネットエージェント開発テクニック」という書籍を購入しました。
 Node.jsやWebクローラー開発に触れたことがありませんでしたが、書籍を読みつつ、手を動かしてみることで、簡単なWebクローラー作成ができるようになったと思います。ここでは、個人的な学習のまとめを書いてみたいと思います。
 なお、機械学習については、まだ理解が追いついていませんのでここでは記述しません。

前提

  • Java,JavaScript,HTMLを使ったWebアプリケーションの開発技術については学習経験があります。
  • Node.jsは未経験。
  • Windows環境を使用。
  • Node.js バージョン4.2.6 を使用。

Node.jsとは

JavaScriptエンジンの一つで、コマンドラインから利用できる。最も普及しているJavaScriptエンジンは、各種ブラウザであるが、セキュリティ面の考慮から、いろいろ制限が多い。Node.jsでは、ファイル処理やネットワーク処理などもできる。さらに、パッケージマネージャー「npm」があり、便利な機能を拡張することが容易。

Node.jsインストール方法

公式サイトから、MSIファイルをダウンロードして、インストール。
※EXEファイル形式もあったけど、npmが入っていなかった。

Node.js
https://nodejs.org/en/

インストールが終わると、スタートメニューに「Node.js command prompt」が登録されている。これを起動して、次のコマンドを実行できればOK。Windows標準のコマンドプロンプトからも実行できた。

node -v

パッケージマネージャー npm

npmは、Node.jsで、モジュール(拡張機能)をインストールしたりするためのパッケージマネージャー。インストールしたモジュールの管理場所は、グローバルとローカルの2種類がある。
次のようにコマンドラインから使用できる。

npm -v

主な使い方。

npm -h ヘルプを表示。

npm install モジュール名 モジュールをインストールする。
npm uninstall モジュール名 モジュールをアンインストールする。
npm list インストールされているモジュールの一覧を表示する。
※上記コマンドでは、ローカル環境を対象とする。ローカル環境とはカレントディレクトリのこと。グローバル環境を対象とする場合は、「-g」オプションをつける。

npm root -g グローバル環境のパスを表示する。ホームディレクトリ\AppData\Roaming\npm\node_modules となるようです。

私が試した時には、グローバル環境にインストールしたモジュールを使おうとして、「Cannot find module XXX」とエラー表示されることがありました。その場合、次のように環境変数を設定すると、解決しました。

set NODE_PATH=グローバル環境のパス(npm root -gの結果)

簡単なサンプル

ハローワールドを出力させる。

ワンライナーで実行。

node -e "console.log('Hello World');"

スクリプトを作成して実行する。

helloworld.js
console.log("Hello World");
node helloworld.js

Node.jsのリファレンス
Node.js v4.2.6 Manual & Documentation

Webページダウンロード(cheerio-httpcliモジュール)

静的なページや、RSS, XMLダウンロードなどに使用可能。逆に、jQuery,Ajaxを多用したようなページでは使用困難な模様。jQuery風に要素を指定できるのが便利。

モジュールインストール

npm install -g cheerio-httpcli

私がインストールしたバージョン
cheerio-httpcli 0.6.4

簡単なスクリプト
Googleで「node.js」を検索して、ページタイトルを標準出力する。

cheerio-httpcli-01.js
var client = require('cheerio-httpcli');

client.fetch('http://www.google.com/search',
  { q: 'node.js' },
  function (err, $, res) {
    console.log($('title').text());
});

実行

node cheerio-httpcli-01.js

参考ページ
cheerio-httpcli
Node.jsのスクレイピングモジュール「cheerio-httpcli」が第3形態に進化したようです - Qiita
Node.jsのスクレイピングモジュール「cheerio-httpcli」が大規模アップデートして帰ってきた - Qiita

Webページダウンロード(PhantomJS,CasperJSモジュール)

PhantomJSが画面表示しないWebブラウザのようなもの、CasperJSがPhantomJSを簡単に使うためのもの、らしい。
cheerio-httpcliでは操作できなかったWebページでも操作できた。コマンドラインから、casperjsコマンドでJavaScriptを実行することになるが、JavaScript内で使うことができるモジュールには制限がある模様。
Pythonのインストールが必要だった。

モジュールインストール

npm install -g phantomjs
npm install -g casperjs

私がインストールしたバージョン
PhantomJS 2.1.1
CasperJS 1.1.0-beta5

簡単なスクリプト
Googleで「node.js」を検索して、ページタイトルを標準出力する。

casperjs-01.js
var casper = require("casper").create();

casper.start("http://www.google.com/search?q=node.js", function(){
  this.echo("Title: " + this.getTitle());
});

casper.run();

実行

casperjs casperjs-01.js

参考
CasperJS documentation — CasperJS 1.1.0-DEV documentation

メール送信

Yahoo!JAPANメールを使って、メール送信してみる。

モジュールインストール
Yahoo!JAPANメールを使う場合、SMTPサーバを指定してメール送信する。SMTPサーバを使う場合、nodemailer-smtp-transportをインストールしないとダメだった。nodemailerのバージョンによるのかもしれない。

npm install -g nodemailer
npm install -g nodemailer-smtp-transport

私がインストールしたバージョン
nodemailer 2.1.0
nodemailer-smtp-transport 2.2.0

簡単なスクリプト

nodemailer01.js
// 実行方法
if (process.argv.length <= 2) {
  console.info("Usage: node nodemailer01 user pass");
  process.exit();
}
var user = process.argv[2];
var pass = process.argv[3];

// SMTPトランスポート作成
var smtpConfig = {
  host: "smtp.mail.yahoo.co.jp",
  port: 465,
  secure: true,
  auth: {
    user: user,
    pass: pass
  },
  // logger: true,
  // debug: true
};
var nodemailer = require("nodemailer");
var smtpTransport = require("nodemailer-smtp-transport");
var transport = nodemailer.createTransport(smtpTransport(smtpConfig));

// メールアドレス
var address = user + "@yahoo.co.jp";

// メール情報の作成
var mailOptions = {
  from: address,
  to: address,
  // from: '"Sender Name" <' + address + '>',
  // to: '"Receiver Name" <' + address + '>',
  subject: "テストメール",
  text: "テストメールです。"
};

// メール送信
transport.sendMail(mailOptions, function(error, response){
  if (error) {
    console.log(error);
    throw error;
  } else {
    console.log("Message sent: " + response.message);
  }
  transport.close();
});

参考
Node.jsでメール送信が出来る – 野村空っぽい

補助的な機能

実行環境取得

console.log("カレントディレクトリ\n" + process.cwd());
console.log("スクリプトパス(絶対パス)\n" + __filename);
console.log("スクリプトディレクトリ\n" + __dirname);
var path = require("path");
console.log("スクリプトディレクトリ\n" + path.dirname(__filename));
console.log("スクリプト名\n" + path.basename(__filename));
console.log("スクリプト名(拡張子なし)\n" + path.basename(__filename, path.extname(__filename)));
console.log("スクリプト拡張子\n" + path.extname(__filename));
console.log("実行時引数\n", process.argv);
console.log("実行時引数の数\n", process.argv.length);
console.log("Node.jsコマンド\n" + process.argv[0]);
console.log("スクリプトパス\n" + process.argv[1]);
var homedir = process.env[process.platform == "win32" ? "USERPROFILE" : "HOME"];
console.log("ホームディレクトリ\n" + homedir);

参考
Web Tips Plus: node.js ホームディレクトリのパスを取得

環境に合った改行コード

var os = require("os");
console.log("[" + os.EOL + "]");

メッセージ出力

指定メッセージを出力する。

console.log("Hello world.");
console.info("Info log");
console.warn("Warn log");
console.error("Error log");
console.trace("Trace log"); //スタックトレースが出力される。

タイムスタンプを付加してメッセージ出力する。

var infolog = require("util").log;
infolog("Hello world.");

出力/非出力を切り替え可能なメッセージ出力。
出力したい場合は、環境変数NODE_DEBUGに、debuglog関数の引数と同じ文字列を指定しておく。カンマで区切って複数指定することも可能。

var debuglog = require("util").debuglog("myapp");
debuglog("デバッグログです。");
set NODE_DEBUG=myapp

正規表現

簡単に正規表現が使える。あ、これはフツーのJavaScriptの機能だ。

console.log("abcde12345".match(/bcd/g)); //-> [ 'bcd' ]
console.log("abcde12345".replace(/bcd/g, "BCD")); //=> aBCDe12345

参考
文字列(String)
正規表現(RegExp)

設定ファイル(configモジュール)

モジュールインストール

npm install -g config

簡単なスクリプト

script/nodejs01.js
var config = require("config");
console.log(config.test01);

簡単な設定ファイル
JSON5など、いくつかの形式が使える。

config/default.json5
// default.json5
{
  "test01": "hello world",
}

参考
node.jsのいろいろなモジュール13 – node-configで設定ファイルを切り替えたりする | Developers.IO

ファイル入出力

var fs = require("fs");

fs.writeFileSync("./file-01_out.txt", "ハローワールド", {encoding:"UTF-8"});

var text = fs.readFileSync("./file-01_out.txt", {encoding:"UTF-8"});
console.log(text);

参考
File System Node.js v4.3.1 Manual & Documentation

文字コード

Node.jsでは、内部的にはUTF-16が使用されているらしい。Node.jsは、Shift_JISには対応していないらしいので、Shift_JISを扱うときは、文字コード変換するモジュールが必要。

モジュールインストール

npm install -g iconv-lite

私がインストールしたバージョン
iconv-lite 0.4.13

iconv-liteで対応している日本語文字コードは、UTF-8, CP932, Shift_JIS, EUC-JP。個人的にはこれだけあれば十分だと思う。

var iconv = require("iconv-lite");
var fs = require("fs");

fs.writeFileSync(
  "./iconv-lite-01_out.txt",
  iconv.encode("ハローワールド", "Shift_JIS"),
  "binary");

var text = iconv.decode(
  new Buffer(fs.readFileSync("./iconv-lite-01_out.txt", "binary"), "binary"),
  "Shift_JIS");
console.log(text);

参考
GitHub - ashtuchkin/iconv-lite: Convert character encodings in pure javascript.

外部コマンド実行

同期、非同期で実行することが可能。実行する外部コマンドが標準出力などをするときは、文字コードに注意する。

同期的に、dirコマンドを実行してみる。

var childProcess = require("child_process");
var iconv = require("iconv-lite");
var buffer = childProcess.execSync("dir",
  {
    timeout: 60 * 1000, // タイムアウト1分
  });
console.log(iconv.decode(buffer, "Shift_JIS"));

参考
Child Process Node.js v4.3.1 Manual & Documentation

暗号化・復号化

Node.js標準機能のcryptoで、各種アルゴリズムで、暗号化・復号化ができる。

var crypto = require("crypto");

if (process.argv.length <= 2) {
  console.log("Usage: node crypto03.js アルゴリズム 暗号化キー 暗号化対象文字列");
  console.log("主要なアルゴリズム");
  console.log("aes128, aes192, aes256 - https://ja.wikipedia.org/wiki/Advanced_Encryption_Standard");
  console.log("des, des3 - https://ja.wikipedia.org/wiki/Data_Encryption_Standard");
  console.log("blowfish - https://ja.wikipedia.org/wiki/Blowfish");
  console.log("アルゴリズム一覧");
  var cipers = crypto.getCiphers();
  console.log(cipers);
  return;
}

// アルゴリズム
var algorithm = process.argv[2];
console.log("アルゴリズム: " + algorithm);

// 暗号化キー
var key = process.argv[3];
console.log("暗号化キー: " + key);

// 暗号化対象文字列
var plainText = process.argv[4];
console.log("暗号化前: " + plainText);

// 暗号化
var cipher = crypto.createCipher(algorithm, key);
var cryptedText = cipher.update(plainText, "utf8", "hex");
cryptedText += cipher.final("hex");
console.log("暗号化後: " + cryptedText);

// 復号化
var decipher = crypto.createDecipher(algorithm, key);
var decryptedText = decipher.update(cryptedText, "hex", "utf8");
decryptedText += decipher.final("utf8");
console.log("復号化後: " + decryptedText);

JSONとJavaScriptオブジェクトの相互変換

var obj = {
  "item1": "value1"
};

var jsonText = JSON.stringify(obj);
console.log(jsonText);

var jsonObj = JSON.parse(jsonText);
console.log(jsonObj);

XML/RSS/HTMLの解析

cheerioを使うと、jQuery風に解析出来て楽。

モジュールインストール

npm install -g cheerio

私がインストールしたバージョン
cheerio 0.20.0

簡単なスクリプト

var html = ""
  + "<html>"
  + "<body>"
  + "<h1>タイトル</h1>"
  + "</body>"
  + "</html>"
  ;
var cheerio = require("cheerio");
$ = require("cheerio").load(html);
console.log($.html());
console.log($("h1").text());

参考
GitHub - cheeriojs/cheerio: Fast, flexible, and lean implementation of core jQuery designed specifically for the server.

CSVデータの読み書き

comma-separated-valuesというモジュールをインストールすると、CSVデータを簡単に扱えるようになる。

私がインストールしたバージョン
comma-separated-values 3.6.4

簡単なスクリプト

var data = ""
  + "h1,h2,h3\r\n"
  + "v11,v12,v13\r\n"
  + "v21,v22,v23\r\n"
  + "v31,v32,v33\r\n"
  ;

var CSV = require("comma-separated-values");

// CSVテキストを読み込み、2次元配列を作成する。
var csvArray = new CSV(data).parse();
console.log(csvArray);
// ->出力結果
// [ [ 'h1', 'h2', 'h3' ],
//   [ 'v11', 'v12', 'v13' ],
//   [ 'v21', 'v22', 'v23' ],
//   [ 'v31', 'v32', 'v33' ] ]

// CSVテキストを読み込み、オブジェクト配列を作成する。
var csvObjs = new CSV(data, {header:true}).parse();
console.log(csvObjs);
// ->出力結果
// [ { h1: 'v11', h2: 'v12', h3: 'v13' },
//   { h1: 'v21', h2: 'v22', h3: 'v23' },
//   { h1: 'v31', h2: 'v32', h3: 'v33' } ]

// オブジェクト配列を、CSVテキストに変換する。
var csvText = new CSV(csvObjs).encode();
console.log(csvText);
// ->出力結果
// "v11","v12","v13"
// "v21","v22","v23"
// "v31","v32","v33"

参考
comma-separated-values

以上で、学習したことを一通り書いてみたはず。

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
ユーザーは見つかりませんでした