JSON
jq
nhkapi

NHK番組表APIからJSONデータを取得してjqで編集する(データ編集編)

More than 1 year has passed since last update.

はじめに

前回は、NHK番組表APIからJSONデータを取得する方法を説明しました。
今回は、JSONデータをjqコマンドで編集して必要な情報(開始日時、番組時間、番組タイトル)を取得したいと思います。

1. JSONデータをjqで編集するスクリプト

edit_sample_json.sh

#!/bin/sh

title_str="基礎英語3|ラジオ英会話"

cat ./sample.json \
 | jq -r --arg reg_str $title_str '

    def mk_sec(t): t | strptime("%Y-%m-%dT%H:%M:%S+09:00") | mktime;
    def mk_attime(s): mk_sec(s) | strftime("%H:%M %m/%d/%y");

    .list.r2[]
      | select(.title | test($reg_str))
      | [ mk_attime(.start_time),
          mk_sec(.end_time) - mk_sec(.start_time),
          .title ] | @csv
' 

2. スクリプト実行結果

$ ./edit_sample.json
"06:30 11/03/17",900,"基礎英語3「Review24」"
"06:45 11/03/17",900,"ラジオ英会話「スペシャル・ウィーク」(復習)"
"12:25 11/03/17",900,"ラジオ英会話「スペシャル・ウィーク」(復習)"
"15:45 11/03/17",900,"ラジオ英会話「スペシャル・ウィーク」(復習)"
"19:15 11/03/17",900,"基礎英語3「Review24」"
"21:30 11/03/17",900,"基礎英語3「Review24」"
"21:45 11/03/17",900,"ラジオ英会話「スペシャル・ウィーク」(復習)"

※再放送を識別する情報は、提供されるJSONデータには含まれていません。重複を除外したい場合は、タイトルをuniqにする処理が必要です。

3. スクリプト解説

  • 特定の番組情報取得

APIで取得したJSONには
"title": "基礎英語3「Review24」"
のように放送日固有のタイトルが格納されているので、「基礎英語3」の情報を毎日取得したいと思ったらタイトル行と部分一致させて情報取得する必要があります。(番組をシリーズで識別するためのキーがあるはずと探してみましたが見つかりませんでした。)
jqの組み込み関数にtest()があり、正規表現が使用できるのでこれを使用しています。
「基礎英語3」と「ラジオ英会話」のデータを取得したかったのでパイプ「|」でつないで正規表現文字列を作っています。
title_str="基礎英語3|ラジオ英会話"
オプション --argを使用して、jqスクリプト内で使用可能な変数を指定しています。

正規表現文字列の部分は、引数で受け取るようしてもいいし、対象の番組がたくさんある場合は、以下のやりかたでファイルから作成するようにしてもいいと思います。

1.データを取得したい番組名を入れたファイルを作成する
cat ./title.txt

基礎英語3
ラジオ英会話
番組3
番組4
番組5
2.ファイルを読み込んでパイプでつなぐ
title_str=$(echo $(cat ./title.txt) | sed -e "s/\s/|/g")

echo $title_str
基礎英語3|ラジオ英会話|番組3|番組4|番組5
  • 番組時間の取得

開始時間と終了時間は以下のようにiso形式で保存されています。
"start_time": "2017-11-03T06:45:00+09:00",
"end_time": "2017-11-03T07:00:00+09:00",

時刻のフォーマット変換と計算が必要なのでiso形式をjqの組み込み関数でUNIX時間に変換します。
スクリプトが長くなるので関数として定義しました。

UNIX時間(秒)の算出を関数化しました。
def mk_sec(t): t | strptime("%Y-%m-%dT%H:%M:%S+09:00") | mktime;

UNIX時間(秒)を元に必要な時刻フォーマットに変更しています。(atコマンド用のフォーマット)
def mk_attime(s): mk_sec(s) | strftime("%H:%M %m/%d/%y");

  • 文字列フォーマット

@csvを指定して出力される文字列をCSV形式にして出力しています。
csvにしておけば、このあとそれぞれの値が扱いやすくなると思います。

4. さいごに

当初、JSONの編集をawkでやっていたのですがスクリプトが思いのほか長くなってしまいました。iso形式の扱いがひとつのネックでした。その点、jqは時刻の扱いが楽にできたのでかなり短くまとめることができました。jqに慣れてしまえば、JSONデータの編集がかなり楽になると思います。スクリプトの説明がかなりおおざっぱになってしまったので質問があれば気軽にコメントしてください。