国会会議録をAPI経由で取得する

# 国会会議録をAPI経由で取得する

## TL; DR

pythonからAPI叩いて、任意の国会議事録を収集します。

## 1. 公式情報

[国会会議録検索システム](https://kokkai.ndl.go.jp/#/)からGUIで検索も出来ますが、[ちゃんとAPIのマニュアルがあります](https://kokkai.ndl.go.jp/api.html)。

## 2. キーワードを指定して検索＆取得する

ここでは、2010年～2019年の10年間の発言を対象として、以下キーワードを含む議事録を収集します。

* 人工知能
* 機械学習
* AI
* ビッグデータ


```python
# -*- coding: utf-8 -*-
"""
Created on Thu Dec 26 15:05:04 2019

@author: boomin

pip install untangle
"""

import urllib
import untangle
import urllib.parse

import re
import pandas as pd
import os

spt = os.sep
pklDir  = "pkl"

def getSpeech(keyword:str):
    start="1" #'#発言の通し番号
    apipath = 'http://kokkai.ndl.go.jp/api/1.0/speech?'

    # 発言内容から、発言者部分を削除するための正規表現
    p = re.compile(r'^○([^ ]+)君?\s(.+)')

    startdate='2010-01-01'
    enddate= '2020-01-01'

    df = pd.DataFrame()

    while start!=None:
        date = []
        speaker = []
        speech = []
        speakerGroup = []
        speakerPosition = []

        url = apipath+urllib.parse.quote(
            'maximumRecords=100&recordPacking=xml'
            + '&from=' + startdate
            + '&until=' + enddate
            + '&any=' + keyword
            + f'&startRecord={start}'
        )
        #Get信号のリクエストの検索結果（XML）
        obj = untangle.parse(url)

        for record in obj.data.records.record:
            speechrecord = record.recordData.speechRecord

            speechdata = speechrecord.speech.cdata.replace("\u3000"," ").replace("\n"," ")
            m = p.search(speechdata)
            if not isinstance(m,type(None)):
                date.append(speechrecord.date.cdata)
                speaker.append(speechrecord.speaker.cdata)
                speech.append(m.group(2))
                speakerGroup.append(speechrecord.speakerGroup.cdata)
                speakerPosition.append(speechrecord.speakerPosition.cdata)

        offset = int(start)-1
        index = [ offset+n for n in list(range(len(date))) ]
        adddf = pd.DataFrame({
            "date":date, 
            "speaker":speaker,
            "speech":speech,
            "speakerGroup":speakerGroup,
            "speakerPosition":speakerPosition,
          }, index=index)
        df = pd.concat([df, adddf ])

        #一度に100件しか帰ってこないので、開始位置を変更して繰り返しGET関数を送信
        try:
            start = obj.data.nextRecordPosition.cdata
            print(f"finished: {start}")
        except:
            pass
            break

    df["date"] = pd.to_datetime(df["date"])
    return df

if __name__ == '__main__':
  
    df1 = getSpeech('人工知能')
    df2 = getSpeech('ＡＩ')
    df3 = getSpeech('ビッグデータ')
    df4 = getSpeech('機械学習')

    df = pd.concat([df1,df2,df3,df4])
    # 重複する発言の削除
    df.drop_duplicates(subset=["date","speaker","speech"], inplace=True)
    df.sort_values(by=["date","speaker"],inplace=True)

    df.reset_index(drop=True, inplace=True)

    pd.to_pickle(df, f"{pklDir}{spt}kokkailog.pkl")
    df.to_csv(f"{pklDir}{spt}kokkailog.tsv", sep="\t")
```

## 3. 取得できたデータ

```python
In[4]: df.tail()
Out[4]: 
#           date speaker  ...         speakerGroup speakerPosition
#4288 2019-12-05     江藤拓  ...          自由民主党・無所属の会          農林水産大臣
#4289 2019-12-05    浜田昌良  ...                  公明党                
#4290 2019-12-05    石井苗子  ...               日本維新の会                
#4291 2019-12-05    緑川貴士  ...  立憲民主・国民・社保・無所属フォーラム                
#4292 2019-12-05   萩生田光一  ...          自由民主党・無所属の会          文部科学大臣
#
#[5 rows x 5 columns]
```