WebAPIからデータを取得、加工して、その結果をcsvファイルとして書き出してみよう!
お題
○以下のURLは架空ユーザーデータを返却するWebAPIである。
○このJSONデータには、nameとcityが含まれているのでこの情報にテストの点数として0-100のランダムな点数を付与したデータを作成する。
○10人分のデータをテストの点数降順に並び替えてresult.csvに出力する。
実行例
以下のようなresult.csvファイルが作成される(name,city,テストの点数)
Clementine Bauch,McKenziehaven,100
Kurtis Weissnat,Howemouth,99
Patricia Lebsack,South Elvis,92
Glenna Reichert,Bartholomebury,82
Clementina DuBuque,Lebsackbury,75
Leanne Graham,Gwenborough,47
Ervin Howell,Wisokyburgh,34
Mrs. Dennis Schulist,South Christy,31
Nicholas Runolfsdottir V,Aliyaview,27
Chelsey Dietrich,Roscoeview,21
Let’s challenge!
WebAPIやJSONパースなど、実務でも多用される処理だ。しかし、Pythonを使えばこの手の処理は驚くほど簡単だ。挑戦してみよう。
作成例
今回はモジュールとして、http通信を標準ライブラリよりも便利に行えるrequestsモジュール。jsonをパースするjsonモジュール。テストの点数をランダムに生成するさいに必要なrandomモジュールをインポートする。
(requestsモジュールが環境に入っていない人はインストールすること)
scores.pyを新規に作成し、以下を記述する。
import requests
import json
import random
Personクラス作成
今回はそれぞれの人が名前とcityとテストの点数を持つのでPersonクラスを作成しよう。以下のようにPersonクラスを追記する。
import requests
import json
import random
#Personクラス
class Person:
#コンストラクタ
def __init__(self,name,city):
self.name=name
self.city=city
#点数をランダムに生成
self.score=random.randint(0,100)
#自分の情報をCSV文字列にするメソッド
def toCSV(self):
return f'{self.name},{self.city},{self.score}'
WebAPIからJSONデータの取得&パース
import requests
import json
import random
#Personクラス
class Person:
#コンストラクタ
def __init__(self,name,city):
self.name=name
self.city=city
#点数をランダムに生成
self.score=random.randint(0,100)
#自分の情報をCSV文字列にするメソッド
def toCSV(self):
return f'{self.name},{self.city},{self.score}'
URL='https://jsonplaceholder.typicode.com/users'
#通信をしてレスポンスを取得する
res=requests.get(URL)
#レスポンスから本文(JSONデータ)を取り出して、パースする
data=json.loads(res.text)
#デバッグプリント
print(data)
実行してみよう。以下のようにコンソールに表示されれば成功だ
○APIから返却されたデータはルートが配列になっているのでループで回しながらデータを作成していく。以下のように追記
import requests
import json
import random
#Personクラス
class Person:
#コンストラクタ
def __init__(self,name,city):
self.name=name
self.city=city
#点数をランダムに生成
self.score=random.randint(0,100)
#自分の情報をCSV文字列にするメソッド
def toCSV(self):
return f'{self.name},{self.city},{self.score}'
URL='https://jsonplaceholder.typicode.com/users'
#通信をしてレスポンスを取得する
res=requests.get(URL)
#レスポンスから本文(JSONデータ)を取り出して、パースする
data=json.loads(res.text)
#デバッグプリント
#print(data)
#Personオブジェクトが入るリスト作成
persons=[]
#jsonデータの件数分回すループ(今回は10件)
for d in data:
#nameとcityを取り出してPersonオブジェクトを作成し、リストに追加
persons.append(Person(d['name'],d['address']['city']))
#リストをテストの点数を降順に並び替え
persons.sort(key=lambda p:-p.score)
#デバッグプリント
print(persons[0].toCSV())
○実行してみよう。以下のように最高得点の人が出力されていれば成功だ。
ファイルの書き込み
無事にデータを取得、加工、並び替えができたようなので最後にファイルに出力しよう。以下のように追記する。
import requests
import json
import random
#Personクラス
class Person:
#コンストラクタ
def __init__(self,name,city):
self.name=name
self.city=city
#点数をランダムに生成
self.score=random.randint(0,100)
#自分の情報をCSV文字列にするメソッド
def toCSV(self):
return f'{self.name},{self.city},{self.score}'
URL='https://jsonplaceholder.typicode.com/users'
#通信をしてレスポンスを取得する
res=requests.get(URL)
#レスポンスから本文(JSONデータ)を取り出して、パースする
data=json.loads(res.text)
#デバッグプリント
#print(data)
#Personオブジェクトが入るリスト作成
persons=[]
#jsonデータの件数分回すループ(今回は10件)
for d in data:
#nameとcityを取り出してPersonオブジェクトを作成し、リストに追加
persons.append(Person(d['name'],d['address']['city']))
#リストをテストの点数を降順に並び替え
persons.sort(key=lambda p:-p.score)
#デバッグプリント
print(persons[0].toCSV())
#result.csvを開いて(無ければ新規に作成される)書き込む
with open('result.csv','w',encoding='utf-8') as file:
#リストから1件ずつ取り出す
for p in persons:
#それぞれcsvで出力して改行
file.write(p.toCSV()+'\n')
○実行してみよう。result.csvが作成され以下のような内容のデータが書き込まれていたら成功だ。
Ervin Howell,Wisokyburgh,98
Chelsey Dietrich,Roscoeview,89
Leanne Graham,Gwenborough,86
Mrs. Dennis Schulist,South Christy,68
Patricia Lebsack,South Elvis,64
Clementine Bauch,McKenziehaven,63
Nicholas Runolfsdottir V,Aliyaview,56
Glenna Reichert,Bartholomebury,48
Kurtis Weissnat,Howemouth,46
Clementina DuBuque,Lebsackbury,20
完成
以上で完成だ。WebAPIからJSONを取得し、パースしていく作業はとても大切だ。しかし、Pythonならばファイルの作成まで含めても数行で作れてしまう。
是非Pythonの軽快さを堪能してもらいたい。
別解
classを作成せずに2次元リストでデータを扱った例
import requests
import random
URL='https://jsonplaceholder.typicode.com/users'
data=requests.get(URL).json()
persons=[[d['name'],d['address']['city'],random.randint(0,100)] for d in data]
persons.sort(key=lambda ls:-ls[2])
with open('result.csv','w',encoding='utf-8') as file:
for p in persons:
file.write(f'{p[0]},{p[1]},{p[2]}\n')
コメント