「退屈なことはPythonにやらせよう」的な作業があったのですが、せっかくなのでPerlでやることにしました。 なぜPerlを選んだのかと言うと、しばらくPerlから遠ざかっていたこともあり、久しぶりに書きたくなったからです。
やりたいことはWeb APIからJSONを取得して、それをCSVに変換してファイル出力するという内容です。
開発環境の事前準備
今回はスポット的に実行できれば良いので、Dockerを使うことにしました。
docker run -v $(pwd):/work -it --rm perl:5.30 /bin/bash
「-it /bin/bash」で起動したDockerコンテナーの中に入るので、そこから必要なCPANモジュールをインストールします。 私はcpanmを使っているのですが、cpanmはRebuild.fmの宮川達彦さんが開発していることでも有名です。
# JSONパースで使います cpanm JSON # HTTPクライアントとして使います cpanm LWP::UserAgent # LWP::UserAgentでHTTPS通信するために使います cpanm LWP::Protocol::https # CSV出力するために使います cpanm Text::CSV_XS
CPANモジュールのインストールが終わったら、「cd /work」でホストとマウントしているディレクトリに移動します。 これで事前準備は完了です。
# 「-v $(pwd):/work」で、ホスト側のカレントディレクトリをコンテナーの/workにマウントしているため cd /work perl your_script.pl
HTTP(S)クライアントによる通信と、JSONパースからのCSV出力サンプル
今回のサンプル用に、適当に作ったJSONファイルをGitHub Gistに用意しました。
作成したperlスクリプトを掲載します。 今回はPerlの復習も目的のひとつにあるので、簡単な解説も続けて記載します。
#!/usr/bin/perl use strict; use warnings; use URI; use LWP::UserAgent; use Data::Dumper; use JSON qw/from_json/; use Text::CSV_XS; use constant JSON_API => "https://gist.githubusercontent.com/konosumi/3e3662e46e8db9283c2ad4d650f69483/raw/f53b78e810d62dc24e5a0864056fc424da668094/blog-perl-lwp-csv-sample.json"; use constant SAVE_CSV_FILE => "./sample.csv"; # HTTPS通信でJSONファイルを取得する my $ua = LWP::UserAgent->new; my $url = URI->new(JSON_API); my $res = $ua->get($url); warn "取得したJSONファイルの内容を出力します"; warn $res->content; # 取得したJSONをパースする my $json = from_json( $res->content ); warn "パースしたJSONの中身を出力します"; warn Dumper $json; # ファイルに書き込むためのCSV文字列を作成する my $csv = Text::CSV_XS->new ({ binary => 1 }); $csv->combine(( $json->{test}->{a}, $json->{test}->{b}, $json->{sample} )); warn "次の内容をCSVファイルに書き込みます"; warn $csv->string; # CSVをファイルに出力します open(FH_CSV, '> ' . SAVE_CSV_FILE); print FH_CSV $csv->string; close(FH_CSV);
Perlの復習
use strict
use strict;
JavaSciptにはStrictモードがあり、ファイルの先頭に"use strict";
と記述するとJSが厳格になります。
Perlにも似たような手法があり、よほどの事情がない限りはファイルの先頭に「use strict;」を記述します。
strictプラグマはPerlの文法チェックを厳しくするためのプラグマです。strictプラグマは、Perlのスクリプトを書くときには、必ず記述するようにしてください。
参考:https://tutorial.perlzemi.com/blog/20130912137895.html
use warnings
use warnings;
use warnings
は警告出力において役立つため、use strict
とセットで記述します。
Perlにおいては、デフォルトの状態では、警告は表示されず、スクリプトが実行されます。warningsプラグマを使えば、警告を表示させることができます。スクリプトを書く場合は、strictプラグマとあわせて、必ず記述するようにしましょう。
参考:https://tutorial.perlzemi.com/blog/20130916137930.html
定数の定義
use constant SAVE_CSV_FILE => "./sample.csv";
Perlでは、「use constant」を使って定数を定義します。
LWP::UserAgentによるHTTP(S)通信
LWP::UserAgentはPerlのHTTPクライアントで、私が新人WEBエンジニアのときにも使っていた、老舗のCPANモジュールです。 LWPの書き方は色々あるのですが、今回は明示的にURIを作成してから通信することにしました。
my $ua = LWP::UserAgent->new; my $url = URI->new(JSON_API); my $res = $ua->get($url);
JSONのパース
JSONモジュールがあるので、それを使います。 JSONクラスにはサブルーチンが色々あるのですが、今回は文字列からのJSONパースなので、from_jsonに限定してインポートしています。
use JSON qw/from_json/; # 取得したJSONをパースする my $json = from_json( $res->content ); warn "パースしたJSONの中身を出力します"; warn Dumper $json;
CSV文字列の作成
Text::CSV_XSを使います。
use Text::CSV_XS; my $csv = Text::CSV_XS->new ({ binary => 1 }); $csv->combine(( $json->{test}->{a}, $json->{test}->{b}, $json->{sample} )); warn "次の内容をCSVファイルに書き込みます"; warn $csv->string;
今回はCSVを作成する例ですが、CSVの読み込みは「Perlプログラミング入門ゼミ」が参考になります。
CSVのファイル出力
Perlでは、標準のファイルハンドルがファイル読み書きの基本形です。
# ファイルハンドルを開く open(FH_CSV, '> ' . SAVE_CSV_FILE); # print [ファイルハンドル] 文字列 print FH_CSV $csv->string; # ファイルハンドルを閉じる close(FH_CSV);
さいごに
しばらくPerlから遠ざかっていたこともあり、新鮮な気持ちで書けました。 一部忘れていた文法もあったのですが、意外と書いてるうちに思い出しました。
ちなみに私は今でもPerlが好きなのですが、理由は単純に変数宣言に「my」があるからです。 なぜと聞かれると困るのですが、「my」を使った変数宣言に、謎の愛着と親近感があります。
なお本記事の執筆では、一部「Perlプログラミング入門ゼミ」を参考にさせていただきました。 この場を借りて、御礼申し上げます。