SplunkのPythonでJSONをCSVにする


Splunkで日本のCOVID19感染状況を表示する(改訂2版)においてpythonを利用しHPからデータをダウンロード、CSVに加工している。

Splunkはpandasが入っていなく、Windowsの人とかだと敷居が高そうなので、Splunk内pythonでなんとかならないか頑張ってみた。

コード

dl_json_to_csv2.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
import json
import csv

headers={'accept': 'application/json', 'content-type': 'application/json'}
url = 'https://www3.nhk.or.jp/news/special/coronavirus/data/47patients-data.json'

response=requests.get(url,headers=headers)
json_obj = response.json()

##日付データの格納
header=["pref"]+[i for i in list(json_obj['category'])]

##感染者数データの格納
lst = [[] for _ in range(len(json_obj['data47']))] ##初期化
for j,json in enumerate(json_obj['data47']):
    lst[j].append(json['name'])
    for json2 in json['data']:
        lst[j].append(json2)

##CSV書き込み
with open('japan_covid19.csv', 'w', encoding='UTF-8',newline='') as f:
    writer = csv.writer(f)
    writer.writerow(header)
    writer.writerows(lst)

なんとかなったのが、以上のコード

splunk
$SPLUNK_HOME/bin/splunk cmd python3 ./dl_json_to_csv2.py

で動作確認済

pythonistaによる添削

dl_json_to_csv2.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
import json
import csv

headers={'accept': 'application/json', 'content-type': 'application/json'}
url = 'https://www3.nhk.or.jp/news/special/coronavirus/data/47patients-data.json'

response=requests.get(url,headers=headers)
json_obj = response.json()

lst = [['pref']+json_obj['category']] + [[json['name']]+json['data'] for json in json_obj['data47']]

with open('japan_covid19.csv', 'w', encoding='UTF-8',newline='') as f:
        writer = csv.writer(f)
        writer.writerows(lst)

あまりにも高度な技能は魔法ですね。

解説

a=['1']
b=['2','3']
c=[a+b]
d=['4']
c+d

の結果は
[['1', '2', '3'], '4']
list[]で囲ってあげるとリスト内リストになる。

d={'data47':[{'name':'4','data':['5','6','7']},{'name':'8','data':['9','10','11']}]}
e=[[json['name']] + json['data'] for json in d['data47']]
e

の結果は
[['4', '5', '6', '7'], ['8', '9', '10', '11']]

したがって

a=['1']
b=['2','3']
c=[a+b]
d={'data47':[{'name':'4','data':['5','6','7']},{'name':'8','data':['9','10','11']}]}
e=[[json['name']] + json['data'] for json in d['data47']]
c+e

[['1', '2', '3'], ['4', '5', '6', '7'], ['8', '9', '10', '11']]

より細かく

eはリストで

  • 内包全体: 変数を使った式 for 変数 in リスト
  • 式: [json['name']] + json['data']
  • 変数: json
  • リスト: d['data47']

例えば

d={'data47':[{'name':'4','data':['5','6','7']},{'name':'8','data':['9','10','11']}]}
e=[json['name'] + json['data'] for json in d['data47']]
e

とするとTypeError: can only concatenate str (not "list") to strとなる。
json['name']の戻りがstrに対してjson['data']list
list同志じゃないと結合ができない。

なんかわかってきた。

まとめ

type ()でいちいち配列がどっちだか確認しながら作っていきました。
リスト内リストを作るところでハマり、不格好なコードになってしまいました。
現在添削中です。pythonistaに添削してもらいました。

綺麗になったら、Splunkダッシュボード用にしたいと思います。