Help us understand the problem. What is going on with this article?

Python:webAPIからJSONデータの読み込み

More than 1 year has passed since last update.

まず、JSONってなんだ?

人間にもコンピュータにもわかりやすいデータ構造らしいです(ざっくり)
JSONとは - Qiita


jsonデータをpythonで読み込むにはjsonライブラリをimportすればできるようになるらしい。

読み込んだらdictionary型と同じ扱い方ができるらしい。(dictinary型についてよくわからないのでここでお勉強します。)

dictionary型について

  • dictionary型はkey(キー)とvalue(値)のセット(要素)になっている
  • javaでいうhashMapみたいなもの?(hashMapうる覚えです)
  • 要素の順序はないため、要素を取り出すためにはキーを指定して取り出すことになる

keyを指定して値を取り出す

test01.py
# -*- coding: utf-8 -*-

dict = {"name": "tamago", "color": "yellow"}

# keyを指定してvalueを取り出す
print dict["name"]
print dict["color"]
test01.pyの出力結果
tamago
yellow

もし、存在しないkeyを指定して取り出そうとすると、Errorになってしまう。

keyとvalueのリストを取得

  • keyのリストを取得
  • valueのリストを取得
  • keyとvalueのリストを取得
test02.py
# -*- coding: utf-8 -*-

dict = {"name": "tamago", "color", "yellow"}

# keyのリストを取得
keyList = dict.keys()
print keyList

# valueのリストの取得
vakList = dict.values()
print valList

# keyとvalueのリストの取得
list = dict.items()
print list
test02.pyの出力結果
['color', 'name']
['yellow', 'tamago']
[('color', 'yellow'), ('name', 'tamago')]

dictionary型には要素の順番はないのでどのように取得できるかはわからない

ざっとdictionaryについては理解できました!!

WebAPIからJSONデータを取得

今回、使用するwebAPIはツイキャスのコメント取得API(コメント取得API - ツイキャス)です

WebAPIからJSONデータを取得するときにはurllibをインポートし、メソッドを使い、取得します
取得したデータをpythonで扱えるようにするにはjsonをインポートし、メソッドを使います

test02.py
# -*- coding: utf-8 -*-

import urllib
import json
import sys
import codecs

# これで、cp932に変換できない文字はなくすことができる
sys.stdout = codecs.getwriter(sys.stdout.encoding)(sys.stdout, errors='ignore')

# webAPIからJSONの形式の文字列の結果をもらう
def dataGet():

    # URIスキーム
    url = 'http://api.twitcasting.tv/api/commentlist?'

    # URIパラメータのデータ 
    param = {
        'user': 'tamago324_pad',    # 取得したい人のID
        'type': 'json'             # 取得するデータの指定
    }

    # URIパラメータの文字列の作成
    paramStr = urllib.urlencode(param)  # type=json&user=tamago324_pad と整形される

    # 読み込むオブジェクトの作成
    readObj = urllib.urlopen(url + paramStr)

    # webAPIからのJSONを取得
    response = readObj.read()

    # print type(response)  # >> <type 'str'>

    return response

# webAPIから取得したデータをJSONに変換する
def jsonConversion(jsonStr):

    # webAPIから取得したJSONデータをpythonで使える形に変換する
    data = json.loads(jsonStr)
    return data

    # 日本語が u'\u767d' のようになってしまうため、Unicodeに変換する
    # return json.dumps(data[0], ensure_ascii=False)

# コメントの投稿時間をh:mm:ssに変換する
def getElapsedTime(duration):

    secStr = ""
    minStr = ""

    hourInt = duration / 3600
    minInt = (duration -3600 * hourInt) / 60
    secInt = duration % 60

    if minInt <= 9:
        minStr = "0" + str(minInt)
    else:
        minStr = str(minInt)

    if secInt <= 9:
        secStr = "0" + str(secInt)
    else:
        secStr = str(secInt)

    if hourInt >= 1:
        return str(hourInt) + ":" + minStr + ":" + secStr
    else:
        return minStr + ":" + secStr

if __name__ == '__main__':

    resStr = dataGet()
    res = jsonConversion(resStr)

    # 取得したデータを表示する
    for item in res:
        print getElapsedTime(item['duration']) + " " + item['userstatus']['name'] + " " + item['message']

10:14 たまたまご テスト
09:49 たまたまご コメント

WebAPIからJSONデータの取得

def jsonGet(): ではwebAPIからJSONデータを取得しています
urllib.urlencode()でdictionaryからURIパラメータの文字列を作成しています。このメソッドで返される文字列はkey=valueの形で複数ある場合には&で結合されていきます(例: key1=value1&key2=value2 )
dictionaryには順序はないので結合される順番は指定できません

urllib.urlopen() でJSONデータを読み込むためのオブジェクト(object)を作成している

作成したオブジェクトのメソッド(object.read())でwebAPIからJSONデータを取得している
戻り値はstr型で返ってくるらしい

取得したデータをPythonで扱えるJSONへ変換

json.loads()で取得したJSONをpythonで扱えるように変換する。しかし、unicodeで返してくるため日本語が\u3063のようになってしまうjson.dumps(data, ensure_ascii=False)でしっかりと日本語が表示できた!と思ったら文字列になっていた...datalistだったのに...
これは一つ一つunicodeからstrに変換していくしかないのか...

どうしようか悩んでいたけど、ひとつだけコメントを取得してみようとおもい、prinnt data[0]['message']で表示してみると、しっかりと日本語で表示されたんです!!!が、コメントにが含まれていて、表示しようとしたらUnicodeEncodeError: 'cp932' codec can't encode character u'\ua4b3' in position 0: illegal multibyte sequenceというエラーがでてきた

UnicodeEncodeError でコンソールに文字を表示できないときの対処
cp932で表現できない文字がたまに混ざるユニコード文字列をWindowsのコンソールにprintしたい場合 - 西尾泰和のはてなダイアリー
sys.stdout = codecs.getwriter(sys.stdout.encoding)(sys.stdout, errors='ignore')とかくことでcp932で表現できない文字は表示しないようにできる(仕組みはわかっていないです...こんど解明しようと思っております)

今はコンソールでやっていますが、windowsアプリなどで表示できれば見た目ももっとよくできるかと思います

辞書(ディクショナリ) - Python入門
ライブラリ:json - Life with Python
20.5. urllib — URL による任意のリソースへのアクセス — Python 2.7.x ドキュメント
PythonでYahoo APIを使ってみる – BTY備忘録
Pythonでのget,post通信メモ - Qiita
日本語を含むUnicodeのJSON文字列を得る. - Qiita
18.2. json — JSON エンコーダおよびデコーダ — Python 2.7.x ドキュメント

tamago324
PythonとかVimとか
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away