Javaで日時を扱う(Java7まで)
Java8では、日時を扱うクラス群が様変わりしてしまいました。これを機に、日時の扱いをまとめてみたいと思います。今回は、Java7までの日時、次回は、Java8での日時を書きたいと思います。
Java7までは、主に、Dateクラス、Calendarクラスを使いますね。Apache Commons LangのDateUtils、DateFormatUtilsも使えると便利。
Apache Commons Lang について
- https://commons.apache.org/proper/commons-lang/
- バージョン3.2では、Java6以上が必要。
- バージョン3.0では、Java5以上が必要。
- バージョン2.xは、Java1.4で使用可能。
現在/指定日時の作成
Dateクラスの現在/指定日時を作成する。
// 現在日時 Date nowDate1 = new Date(); // 文字列→Date DateFormat dateTimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); Date date1 = dateTimeFormat.parse("2016/5/2 15:00:00"); // 文字列→Date(Apache Commons Lang) // ※Java5から、書式引数を可変長引数として記述できるようになった。 Date date1b = DateUtils.parseDate("2016/5/2 15:00:00", "yyyy/MM/dd HH:mm:ss"); Date date1c = DateUtils.parseDate("2016-5-2 15:00:00", "yyyy/MM/dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss"); // Calendar→Date Date date2 = new GregorianCalendar(2016, 5 - 1, 2, 15, 0, 0).getTime(); // long→Date Date date3 = new Date(System.currentTimeMillis());
Calendarクラスの現在/指定日時を作成する。
// 現在日時 Calendar nowCal1 = Calendar.getInstance(); // 指定日時 Calendar cal1 = new GregorianCalendar(2016, 5 - 1, 2, 15, 0, 0); // Date→Calendar Calendar cal2 = Calendar.getInstance(); cal2.setTime(date1); // Date→Calendar(Apache Commons Lang) Calendar cal2b = DateUtils.toCalendar(date1); // long→Calendar Calendar cal3 = Calendar.getInstance(); cal3.setTimeInMillis(System.currentTimeMillis());
long型(ミリ秒)の現在/指定日時を作成する。
// 現在日時 long nowMsec1 = System.currentTimeMillis(); // 指定日時 long msec1 = System.currentTimeMillis() - 24 * 60 * 60 * 1000; // Date→long long msec2 = date1.getTime(); // Calendar→long long msec3 = cal1.getTimeInMillis();
文字列の現在/指定日時を作成する。
// Date→文字列 DateFormat timestampFormat1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS"); String str1 = timestampFormat1.format(date1); // Date→文字列(Apache Commons Lang) String str1b = DateFormatUtils.format(date1, "yyyy/MM/dd HH:mm:ss.SSS"); // Calendar→文字列 String str2 = format.format(cal1.getTime()); // long→文字列 String str3 = format.format(new Date(msec1));
日時から日付の取り出し
// Date 日時→日付(時刻ゼロ) Calendar tmpCal1 = Calendar.getInstance(); tmpCal1.setTime(date1); Calendar tmpCal2 = new GregorianCalendar(tmpCal1.get(Calendar.YEAR), tmpCal1.get(Calendar.MONTH), tmpCal1.get(Calendar.DATE)); Date ymdDate1 = tmpCal2.getTime(); // Calendar 日時→日付(時刻ゼロ) Calendar ymdCal1 = new GregorianCalendar(cal1.get(Calendar.YEAR), cal1.get(Calendar.MONTH), cal1.get(Calendar.DATE)); // Date 日時→日付(時刻ゼロ)(Apache Commons Lang) Date ymdDate2 = DateUtils.truncate(date1, Calendar.DATE); // Calendar 日時→日付(時刻ゼロ)(Apache Commons Lang) Calendar ymdCal2 = DateUtils.truncate(cal1, Calendar.DATE); // 上記以外に、書式"yyyy/MM/dd"のフォーマットで文字列として取得することも可能。
日時から時刻の取り出し
// 時刻のみを取り出すことは出来ない模様。 // 必要なら、書式"HH:mm:ss"のフォーマットで文字列として取得する(?)
曜日の取得
// Dateから曜日取得 // ※ロケールによって曜日の表記が変わる。 DateFormat weekFormat1 = new SimpleDateFormat("E", Locale.JAPANESE); DateFormat weekFormat2 = new SimpleDateFormat("EEEE", Locale.JAPANESE); String weekStr1 = weekFormat1.format(date1); String weekStr2 = weekFormat2.format(date1); // Calendarから曜日取得 int weekInt1 = cal1.get(Calendar.DAY_OF_WEEK); String[] weekNames = new String[] { "日", "月", "火", "水", "木", "金", "土" }; String weekStr3 = weekNames[weekInt1 - 1]; // Java6では、Calendar.getDisplayNameメソッドが使える。 String weekStr4 = cal1.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.JAPANESE); String weekStr5 = cal1.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.JAPANESE); // Dateから曜日取得(Apache Commons Lang) // ※ロケールによって曜日の表記が変わる。 String weekStr6 = DateFormatUtils.format(date1, "E", Locale.JAPANESE); String weekStr7 = DateFormatUtils.format(date1, "EEEE", Locale.JAPANESE); // Calendarから曜日取得(Apache Commons Lang) // ※ロケールによって曜日の表記が変わる。 String weekStr8 = DateFormatUtils.format(cal1, "E", Locale.JAPANESE); String weekStr9 = DateFormatUtils.format(cal1, "EEEE", Locale.JAPANESE);
日時計算
加算/減算
// Date 1秒後、1日後 // ※Java5では、TimeUnitが使えるようになった。 Date nextSecDate = new Date(msec1 + TimeUnit.SECONDS.toMillis(1)); Date nextDayDate = new Date(msec1 + TimeUnit.DAYS.toMillis(1)); // Calendar 1秒後、1日後、1ヶ月後 Calendar nextSecCal = (Calendar) cal1.clone(); nextSecCal.add(Calendar.SECOND, 1); Calendar nextDayCal = (Calendar) cal1.clone(); nextDayCal.add(Calendar.DATE, 1); Calendar nextMonthCal = (Calendar) cal1.clone(); nextMonthCal.add(Calendar.MONTH, 1); // Date 1秒後、1日後(Apache Commons Lang) Date nextSecDate2 = DateUtils.addSeconds(date1, 1); Date nextDayDate2 = DateUtils.addDays(date1, 1); Date nextMonthDate2 = DateUtils.addMonths(date1, 1);
月初/月末を求める。
// Calendar 月初、月末 Calendar monthBeginning = (Calendar) cal1.clone(); monthBeginning.set(Calendar.DATE, 1); Calendar monthEnd = (Calendar) cal1.clone(); monthEnd.set(Calendar.DATE, cal1.getActualMaximum(Calendar.DATE));
差を求める。
// Date 日時の差 ミリ秒単位、日数単位(切り捨て) // ※日付の差がほしいときは、日時→日付のみに変換して計算する。 long dateDiffMsec = nextDayDate.getTime() - date1.getTime(); long dateDiffDays = (nextDayDate.getTime() - date1.getTime()) / TimeUnit.DAYS.toMillis(1); // Calendar 日時の差 ミリ秒単位、日数単位(切り捨て) // ※日付の差がほしいときは、日時→日付のみに変換して計算する。 long calDiffMsec = nextDayCal.getTimeInMillis() - cal1.getTimeInMillis(); long calDiffDays = (nextDayCal.getTimeInMillis() - cal1.getTimeInMillis()) / TimeUnit.DAYS.toMillis(1); // Date 日付の差(Apache Commons Lang) long dateDiffDays2 = (DateUtils.truncate(nextDayDate, Calendar.DATE).getTime() - DateUtils.truncate(date1, Calendar.DATE).getTime()) / TimeUnit.DAYS.toMillis(1); // Calendar 日付の差(Apache Commons Lang) long calDiffDays2 = (DateUtils.truncate(nextDayCal, Calendar.DATE).getTimeInMillis() - DateUtils.truncate(cal1, Calendar.DATE).getTimeInMillis()) / TimeUnit.DAYS.toMillis(1);
比較する。
// Dateの前後比較 boolean dateBeforeFlag = date1.before(nextDayDate); boolean dateAfterFlag = nextDayDate.after(date1); // Calendarの前後比較 boolean calBeforeFlag = cal1.before(nextDayCal); boolean calAfterFlag = nextDayCal.after(cal1); // Date 日付一致確認(Apache Commons Lang) // ※時刻は無視して、日付のみ比較される。 boolean dateSameFlag = DateUtils.isSameDay(date1, nextSecDate); // Calendar 日付一致確認(Apache Commons Lang) // ※時刻は無視して、日付のみ比較される。 boolean calSameFlag = DateUtils.isSameDay(cal1, nextSecCal);
参考
- Java日付処理メモ(Hishidama's Java Date Memo) http://www.ne.jp/asahi/hishidama/home/tech/java/date.html
- 日時に関する情報を取得する(get) - Calendarクラス http://www.javadrive.jp/start/calendar/index2.html
ラズパイでJava8を使う
自分のRaspberry Piに、Java8をインストールしたので、メモを残しておきます。特に、難しいことはありませんでした。
事前確認
現在のJavaインストール状態を確認します。Java7がインストールされていました。
$ java -version java version "1.7.0_40" Java(TM) SE Runtime Environment (build 1.7.0_40-b43) Java HotSpot(TM) Client VM (build 24.0-b56, mixed mode) $ $ which java /usr/bin/java $ ls -l /usr/bin/java lrwxrwxrwx 1 root root 22 Jan 8 2014 /usr/bin/java -> /etc/alternatives/java $ ls -l /etc/alternatives/java lrwxrwxrwx 1 root root 44 Jan 8 2014 /etc/alternatives/java -> /usr/lib/jvm/jdk-7-oracle-armhf/jre/bin/java $ ls -l /usr/lib/jvm/jdk-7-oracle-armhf/jre/bin/java -rwxr-xr-x 1 root root 5924 Aug 27 2013 /usr/lib/jvm/jdk-7-oracle-armhf/jre/bin/java $ $ dpkg -l | grep jdk ii oracle-java7-jdk 1.7.0+update40 armhf Java? Platform, Standard Edition 7 Development Kit
aptでインストール可能なJavaを確認します。Java8がインストールできることを確認できました。
$ apt-cache search oracle jdk oracle-java7-jdk - Java? Platform, Standard Edition 7 Development Kit oracle-java8-jdk - Java? Platform, Standard Edition 8 Development Kit
OSアップデート
以降の作業を安定して進めるため、次のコマンドでOSをアップデートしました。
$ sudo apt-get update
Java8インストール
次のコマンドでインストールしました。
$ sudo apt-get install oracle-java8-jdk $ dpkg -l | grep oracle ii oracle-java7-jdk 1.7.0+update40 armhf Java? Platform, Standard Edition 7 Development Kit ii oracle-java8-jdk 8 armhf Java? Platform, Standard Edition 8 Development Kit $ java -version java version "1.8.0" Java(TM) SE Runtime Environment (build 1.8.0-b132) Java HotSpot(TM) Client VM (build 25.0-b70, mixed mode) $ which java /usr/bin/java $ ls -l /usr/bin/java lrwxrwxrwx 1 root root 22 1月 8 2014 /usr/bin/java -> /etc/alternatives/java $ ls -l /etc/alternatives/java lrwxrwxrwx 1 root root 51 5月 14 21:47 /etc/alternatives/java -> /usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/jre/bin/java $ ls -l /usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/jre/bin/java -rwxr-xr-x 1 root root 5912 3月 5 2014 /usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/jre/bin/java
設定
環境変数JAVA_HOMEを使用するアプリケーションのため、次の設定をしておきます。
$ JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt
もし、今回インストールする前のJava7を使いたい場合は、次の設定で使えるようになります。
$ JAVA_HOME=/usr/lib/jvm/jdk-7-oracle-armhf $ PATH=${JAVA_HOME}/bin:${PATH} $ java -version java version "1.7.0_40" Java(TM) SE Runtime Environment (build 1.7.0_40-b43) Java HotSpot(TM) Client VM (build 24.0-b56, mixed mode)
ラズパイでRubyのWebクローリング/スクレイピング環境構築メモ(後半)
前回の続きです。
前回は、OSアップデートから、Rubyのインストールまでの手順を書きました。今回は、Webクローリング/スクレイピングするためのRubyジェムをインストールする手順です。
Rubyジェムインストール(Selenium-WebDriver,Nokogiri)
RubyでWebクローリング/スクレイピングするのに便利なジェムとして、Selenium-WebDriver、Nokogiriをインストールすることにしました。インストールは、次のように行いました。
$ gem install selenium-webdriver $ gem install nokogiri
Selenium-WebDriverが動作するように次の設定を行いました。この設定が必須なのかどうかは不明です。
$ sudo vi /etc/hosts $ diff /etc/hosts.bk20160403 /etc/hosts 2,6c2,6 < ::1 localhost ip6-localhost ip6-loopback < fe00::0 ip6-localnet < ff00::0 ip6-mcastprefix < ff02::1 ip6-allnodes < ff02::2 ip6-allrouters --- > #::1 localhost ip6-localhost ip6-loopback > #fe00::0 ip6-localnet > #ff00::0 ip6-mcastprefix > #ff02::1 ip6-allnodes > #ff02::2 ip6-allrouters
Selenium-WebDriverから制御可能なブラウザとして、Firefoxを使うことにしました。Linuxの世界では、Firefoxの代替(?)が、Iceweaselらしいので次のようにしてインストールしました。
$ sudo apt-get install iceweasel
ここまでの手順で、ラズパイのX端末環境において、RubyでWebクローリング/スクレイピングができるようになりました。ただし、X端末が必要ですし、Selenium-WebDriver動作時にはブラウザが画面表示されます。これだと、CUI環境で動作させることはできませんでした。
トラブル体験
hostsファイルのIPv6設定を有効にしたまま、RubyジェムのSelenium-WebDriverを使うと、次のようなエラーが発生しました。
/home/xxx/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/common/port_prober.rb:47:in `initialize': Address family not supported by protocol - socket(2) for "::1" port 7055 (Errno::EAFNOSUPPORT)
このエラーは、次のページをみて解決することができました。感謝!
Firefox(Iceweasel)をインストールせずに、RubyジェムのSelenium-WebDriverを使うと、次のようなエラーが発生しました。
/home/xxx/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/firefox/binary.rb:150:in `path': Could not find Firefox binary (os=linux). Make sure Firefox is installed or set the path manually with Selenium::WebDriver::Firefox::Binary.path= (Selenium::WebDriver::Error::WebDriverError)
このエラー発生時には、次のページにお世話になりました。このぺーじでIceweaselの存在を知り、インストール方法が分かりました。
ここまでの手順の状態(CUI環境で動作させるための環境構築を未実施)にも関わらず、CUI環境でRubyジェムのSelenium-WebDriverを使うと、次のようなエラーが発生しました。
/home/xxx/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/firefox/launcher.rb:90:in `connect_until_stable': unable to obtain stable firefox connection in 60 seconds (127.0.0.1:7055) (Selenium::WebDriver::Error::WebDriverError)
このとき、次のページを見つけて、Headlessの存在を知りました。
Rubyジェムインストール(Headless)
今回初めて知ったのですが、Selenium-WebDriverをCUI環境で動作させるためには、Headlessというジェムがありました。次のようにして、Headlessジェムと、そのジェムを動作させるためのライブラリ類をインストールしました。
$ sudo apt-get install xvfb $ gem install headless $ sudo vi /etc/modprobe.d/ipv6.conf $ diff /etc/modprobe.d/ipv6.conf.bk20160403 /etc/modprobe.d/ipv6.conf 3c3,4 < #alias ipv6 off --- > alias ipv6 off
これで、CUI環境でも、Selenium-WebDriverが動作するようになりました。
トラブル体験
Selenium-WebDriverでブラウザを上手く起動できない時がありました。その場合、`export DISPLAY=:99`としてから、動作させると上手く起動できました。でも、最終的にはその手順をしなくても動作するようになりましたので、必須の手順ではないようです。
Selenium-WebDriverでWebクローリングしたところ、取得したWebページが英語表記になってしまうことがありました。その場合は、Rubyスクリプトで次のようにすることで解決しました。
profile = Selenium::WebDriver::Firefox::Profile.new profile['intl.accept_languages'] = "ja" profile['general.useragent.locale'] = "ja-JP" driver = Selenium::WebDriver.for :firefox, :profile => profile
この際は、こちらのページに助けられました。
Selenium-WebDriverでWebクローリングしたところ、画面表示に時間がかかるページがあり、次のようなエラーが発生しました。
/home/xxx/.rbenv/versions/2.2.4/lib/ruby/2.2.0/net/protocol.rb:158:in `rescue in rbuf_fill': Net::ReadTimeout (Net::ReadTimeout)
その場合、Rubyスクリプトで次のようにすると解決しました。
# タイムアウト値を大きくする(デフォルトは60秒。) client = Selenium::WebDriver::Remote::Http::Default.new client.timeout = 120 driver = Selenium::WebDriver.for :firefox, :http_client => client
この際は、こちらのページに助けられました。
おわり
非常に手間と時間がかかりましたが、環境構築を無事完了できてよかった。
ラズパイでRubyのWebクローリング/スクレイピング環境構築メモ(前半)
先日、ラズパイ上で、Ruby,SeleniumWebDriverのWebクローラー/スクレイピング環境を構築しました。Windows上では環境構築したことがありましたが、Linux系OS上では初めて環境構築しました。手間取ったことも多く、いくつか試行錯誤しながら作業したので、備忘録として手順をまとめたいと思います。
記事が長くなるので、2部構成にします。前半は、OSアップデートから、Rubyのインストール手順です。後半は、Webクローリング/スクレイピングするためのRubyジェムをインストールする手順です。
では、前半です。
動作確認環境
環境構築前は、次のような環境でした。
- Raspberry Pi Model B Rev.2
- Raspbian GNU/Linux 7 (wheezy)
- Linux raspberrypi 3.10.25+ #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014 armv6l GNU/Linux
- Ruby 1.9.3p194 (2012-04-20 revision 35410) [arm-linux-eabihf]
- RubyでWebクローラー/スクレイピングするためのソフトウェアやライブラリなし
今回の作業後は、次の環境になりました。変更点のみ記述します。
作業の流れ
- OSアップデート
- Ruby管理ツールインストール
- Rubyインストール
- Rubyジェムインストール(Selenium-WebDriver,Nokogiri)
- Rubyジェムインストール(Headless)
Rubyをインストールするまでの手順は、次のサイトに従って行いました。
OSアップデート
以降の作業を安定して進めるため、次のコマンドでOSをアップデートしました。
$ sudo apt-get update
補足
今回作業の中で、試行錯誤した際に、次のコマンドも実行しました。必要な作業であったかどうかは不明です。
$ sudo apt-get upgrade
Ruby管理ツールインストール
今回初めて、rbenvの存在を知りました。バージョン違いのRubyをインストール、管理するツールのようです。Rubyには、下位互換性が低いバージョンがいくつかあるようなので、複数バージョンを管理できるツールがあるのは便利ですね。
次のコマンドでインストールしました。
$ sudo apt-get install rbenv $ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
次のコマンドで、インストールしたコマンドが使用可能な状態になったことを確認しました。
$ rbenv -h
トラブル体験
ruby-buildは、apt-getでもインストールできました。その場合、インストール可能なRubyのバージョンが「2.0.0-dev」までしか表示されませんでした。
apt-getとgitの両方のruby-buildをインストールしてしまったことがありました。その場合、`rbenv install --list`ではインストール可能なRubyバージョンが色々表示されましたが、`ruby-build --definitions`では「2.0.0-dev」までしか表示されず、`rbenv install 2.2.4`を実行すると、なぜかコマンドの使用方法が表示され、インストールできませんでした。
apt-getでruby-buildをインストールしたときは、次のコマンドでアンインストールしました。
$ sudo apt-get remove ruby-build $ sudo apt-get autoremove
Rubyインストール
まずは、次のようにして、Rubyで必要となるライブラリ類をインストールし、その設定を行いました。
$ sudo apt-get install autoconf $ sudo apt-get install libreadline-dev $ sudo apt-get install libssl-dev $ sudo apt-get install ruby-dev $ dpkg -l autoconf libreadline-dev libssl-dev ruby-dev $ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile $ . .bashrc
次に、インストール可能なRubyバージョンを確認し、インストールしました。インストールしたRubyバージョンは、普段使っているWindows環境に合わせ2.2.4にしました。インストールには数時間かかり、動作しているかどうか不安になるため、オプション「-v」を付けて、詳細メッセージを表示するようにしました。
$ rbenv install --list $ rbenv install -v 2.2.4 $ rbenv versions 2.2.4 (set by /home/xxx/.rbenv/version)
次のようにして、バージョン2.2.4が適用されていることを確認しました。
$ rbenv global 2.2.4 $ rbenv rehash $ ruby -v ruby 2.2.4p230 (2015-12-16 revision 53155) [armv6l-linux-eabihf] $ gem -v 2.4.5.1
トラブル体験
autoconfのインストールをせずに作業を進めたときは、`rbenv install`のときに、次のようなエラーが発生してしまいました。
/usr/bin/ruby-build: 行 161: autoconf: コマンドが見つかりません
libreadline-devのインストールをせずに作業を進めたときは、`rbenv install`のときに、次のようなエラーが発生してしまいました。
Try running `apt-get install -y libreadline-dev` to fetch missing dependencies.
後半へ
前半は、ここまでです。後半は、こちらです。
初めてのNode.js学習メモ
先日、Webクローラーと機械学習という言葉に惹かれて、「JS+Node.jsによるWebクローラー/ネットエージェント開発テクニック」という書籍を購入しました。
Node.jsやWebクローラー開発に触れたことがありませんでしたが、書籍を読みつつ、手を動かしてみることで、簡単なWebクローラー作成ができるようになったと思います。ここでは、個人的な学習のまとめを書いてみたいと思います。
なお、機械学習については、まだ理解が追いついていませんのでここでは記述しません。
JS+Node.jsによるWebクローラー/ネットエージェント開発テクニック
- 作者: クジラ飛行机
- 出版社/メーカー: ソシム
- 発売日: 2015/08/31
- メディア: 単行本
- この商品を含むブログ (2件) を見る
前提
- 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 command prompt」が登録されている。これを起動して、次のコマンドを実行できればOK。Windows標準のコマンドプロンプトからも実行できた。
node -v
パッケージマネージャー npm
npmは、Node.jsで、モジュール(拡張機能)をインストールしたりするためのパッケージマネージャー。インストールしたモジュールの管理場所は、グローバルとローカルの2種類がある。
次のようにコマンドラインから使用できる。
npm -v
主な使い方。
npm -h | ヘルプを表示。 |
npm install モジュール名 | モジュールをインストールする。※1 |
npm uninstall モジュール名 | モジュールをアンインストールする。※1 |
npm list | インストールされているモジュールの一覧を表示する。※1 |
npm root -g | グローバル環境のパスを表示する。ホームディレクトリ\AppData\Roaming\npm\node_modules となるようです。 |
※1 上記コマンドでは、ローカル環境を対象とする。ローカル環境とはカレントディレクトリのこと。グローバル環境を対象とする場合は、「-g」オプションをつける。
私が試した時には、グローバル環境にインストールしたモジュールを使おうとして、「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.3.1 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(); });
補助的な機能
実行環境取得
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
設定ファイル(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());
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"
以上で、学習したことを一通り書いてみたはず。
Androidアプリ「アプリ間共有の助け Ver.1.3」公開
Androidアプリ「アプリ間共有の助け」公開
このほど、自作Androidアプリ「アプリ間共有の助け」というアプリを公開させていただきました。Androidにおけるアプリ間のデータ共有を少しだけ便利にするアプリです。よろしければ、お使いください!
はじめに
みなさん、Android端末のスマホを使っていると、ちょっとだけ使いにくいな~と思うような機能の1つや2つありますよね? 私は、各アプリの共有メニューを選択し、共有先のアプリを選択するダイアログが出たときに、ちょっとだけ使いにくいな~と、いつも思っていました。ダイアログでは、沢山のアプリが綺麗に並んでいるのですが、私が選択したいアプリは、ずいぶんと下の方にあったりするのです。毎回、スクロールさせるのが煩わしいのです。
そして、Google Playを探すと、共有メニューをカスタマイズできるアプリがいくつもあることを知り、使ってみました。ですが、カスタマイズする手間が煩わしかったりして、自分にはしっくりきませんでした。
であれば、作ってしまえ! ということで今回のアプリを作成しました。(そんなわけなので、かなり自分勝手なアプリですね。)
主な特徴
共有先アプリの選択時に、よく使用するアプリを先頭に表示します。(Android標準機能では、使用頻度を考慮してくれません。)
特定の共有先アプリを「標準」として設定することで、選択画面をスキップして、共有先アプリを起動します。標準設定は、共有元アプリ、共有の種類ごとに設定可能です。(Android標準機能では、共有元によらず、共有の種類のみでしか設定できません。)
標準設定した共有先アプリを解除するのも簡単です。
詳細&ダウンロードは、こちらです。
プログラム
このアプリですが、プログラムをGitHubで公開しています。よろしければ、ご覧下さい。