schedule2018-08-24

20. JSONデータの読み込み

はじめに

言語処理100本ノック 2015

Pythonを勉強するため、東京工業大学の岡崎教授が出題されている言語処理100本ノック 2015を解いていきます。

より深く理解するため、別解や利用したライブラリの解説もまとめていきます。

環境

Python3.6
OS : mac

問題

第3章: 正規表現
Wikipediaの記事を以下のフォーマットで書き出したファイルjawiki-country.json.gzがある.

  • 1行に1記事の情報がJSON形式で格納される
  • 各行には記事名が"title"キーに,記事本文が"text"キーの辞書オブジェクトに格納され,そのオブジェクトがJSON形式で書き出される
  • ファイル全体はgzipで圧縮される

以下の処理を行うプログラムを作成せよ.

20. JSONデータの読み込み
Wikipedia記事のJSONファイルを読み込み,「イギリス」に関する記事本文を表示せよ.問題21-29では,ここで抽出した記事本文に対して実行せよ.

解答

import gzip
import json


def read_wiki(fname, title):
    """指定のタイトルの記事本文を表示する。
    """
    #  ファイルを解凍して読み込む
    with gzip.open(fname, 'rt') as data_file:
        for line in data_file:
            # json to dict
            data_json = json.loads(line)
            # 指定のタイトルの本文を返す
            if data_json['title'] == title:
                return data_json['text']


def main():
    fname = 'jawiki-country.json.gz'
    print(read_wiki(fname, 'イギリス'))

if __name__ == '__main__':
    main()

出力

{{基礎情報 国
|略名 = イギリス
|日本語国名 = グレートブリテン及び北アイルランド連合王国
|公式国名 = {{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:<br/>
*{{lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath}}([[スコットランド・ゲール語]])<br/>
*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon}}([[ウェールズ語]])<br/>
*{{lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann}}([[アイルランド語]])<br/>

(中略)

{{OECD}}
{{イギリス連邦}}

{{デフォルトソート:いきりす}}
[[Category:イギリス|*]]
[[Category:英連邦王国|*]]
[[Category:G8加盟国]]
[[Category:欧州連合加盟国]]
[[Category:海洋国家]]
[[Category:君主国]]
[[Category:島国|くれいとふりてん]]
[[Category:1801年に設立された州・地域]]

解説

3章からWikipediaの記事から問題が出るようになった。
お世話になるイギリスのページはこちら

まずは、jawiki-country.json.gzを確認してみます。 ダウンロードしてツールを使って解凍しました。

中身は1行ごとに国の情報がJSON形式でまとまっています。

{"title":"国名1", "text":"記事本文"}
{"title":"国名2", "text":"記事本文"}

構成がわかったので、Wikipedia記事を読み込み記事を検索する関数read_wiki(fname, title)を作成します。

拡張子.gzはgzipの圧縮ファイルです。pythonの標準モジュールgzipを使って解凍しました。

#  ファイルを解凍して読み込む
with gzip.open(fname, 'rt') as data_file:
    for line in data_file:

これで1行ずつ文字列を読み込みます。 fnameはファイルのパスです。コードとファイルを同じフォルダに置いたので、fname = 'jawiki-country.json.gz'とします。

続いて、1行がJSON形式になっているところを、扱いやすいdictにデコードします。 こちらも、pythonの標準モジュールjsonを使います。

# json to dict
data_json = json.loads(line)

dictへのデコードはjson.load()を利用しました。

>> import
>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
['foo', {'bar': ['baz', None, 1.0, 2]}]

引用:json

jsonのnullは、Noneに変換してくれるみたいです。

# 指定のタイトルの本文を返す
if data_json['title'] == title:
    return data_json['text']

最後に、指定のtitleの記事の本文(text)を返します。

参考

続いての記事

Python3で言語処理100本ノックまとめ

前の問題:19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる

次の問題:21. カテゴリ名を含む行を抽出