まず、JSONってなんだ?
人間にもコンピュータにもわかりやすいデータ構造らしいです(ざっくり)
JSONとは - Qiita
jsonデータをpythonで読み込むにはjsonライブラリをimportすればできるようになるらしい。
読み込んだらdictionary型と同じ扱い方ができるらしい。(dictinary型についてよくわからないのでここでお勉強します。)
dictionary型について
- dictionary型はkey(キー)とvalue(値)のセット(要素)になっている
- javaでいうhashMapみたいなもの?(hashMapうる覚えです)
- 要素の順序はないため、要素を取り出すためにはキーを指定して取り出すことになる
keyを指定して値を取り出す
# -*- coding: utf-8 -*-
dict = {"name": "tamago", "color": "yellow"}
# keyを指定してvalueを取り出す
print dict["name"]
print dict["color"]
tamago
yellow
もし、存在しないkeyを指定して取り出そうとすると、Errorになってしまう。
keyとvalueのリストを取得
- keyのリストを取得
- valueのリストを取得
- keyとvalueのリストを取得
# -*- 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
['color', 'name']
['yellow', 'tamago']
[('color', 'yellow'), ('name', 'tamago')]
dictionary型には要素の順番はないのでどのように取得できるかはわからない
ざっとdictionaryについては理解できました!!
WebAPIからJSONデータを取得
今回、使用するwebAPIはツイキャスのコメント取得API(コメント取得API - ツイキャス)です
WebAPIからJSONデータを取得するときにはurllib
をインポートし、メソッドを使い、取得します
取得したデータをpythonで扱えるようにするにはjson
をインポートし、メソッドを使います
# -*- 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)
でしっかりと日本語が表示できた!と思ったら文字列になっていた...data
はlist
だったのに...
これは一つ一つ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 ドキュメント