WebAPI,JSON,ファイル書き込み

python

WebAPIからデータを取得、加工して、その結果をcsvファイルとして書き出してみよう!

お題

○以下のURLは架空ユーザーデータを返却するWebAPIである。

https://jsonplaceholder.typicode.com/users

○この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')
python
スポンサーリンク
シェアする
mjpurinをフォローする

コメント

タイトルとURLをコピーしました