pandasを使ってwikipediaのテーブルを加工する

# 概要
>
パラリンピックを見ていて、国記号がどの国かわからないことが多かったので、検索programを作るために、初めてpandasを使ってみた。
承認国の追加・削除があっても、常に変更に対応するため、wikipediaからスクレイピングすることとした。
>
## インストールの実施
まず、手始めに肝心のpandasのインストールをpipで実施

```terminal
% pip install pandas
```

次に、pandas.read_html()を使うために、pipでlxml・html5libをインストール

```terminal
% pip install lxml html5lib
```
## programの記述
pandasとrequestsをインポートする。
通常requestsは使わないが、<font color="red">'UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-12: ordinal not in range(128)’</font>のエラーが出るためrequestsを咬ませることで解決した。

```python:ioc.py
import pandas as pd
import requests
```
### □ wikipediaの「IOCコード一覧」のページからコード一覧を取得
```python:ioc.py
# wikipediaの「IOCコード一覧」のページからコード一覧を取得
url = 'https://ja.wikipedia.org/wiki/IOCコード一覧'
# 注１の'UnicodeEncodeError'が出るためrequestsで読み込んだ上でpandasに渡す
r = requests.get(url)
# 引数 match:文字列を指定するとその文字列が含まれる表のみ取得できる
dfs = pd.read_html(r.content, match='コード', header=0)

# key.txtファイル(ioc国記号)とvalue.txtファイル(国名)を同じdirectoryに保存
# to_csv()にsep=" "を追加するとtxtファイルとして保存できる
print()
print('---------txtファイルとして保存----------')
```
これでtableのスクレーピングが完了
次に、取得したDATAをテキストファイルに保存します。
### □ 国コード並びに国名を保存を保存
```python:ioc.py
# 国コードを保存
dfs[0].loc[:,['コード']].to_csv('key.txt', sep=" ", index=False)
# 国名を保存
dfs[0].loc[:,['IOC承認国・地域・団体']].to_csv('value.txt', sep=" ", index=False)
print('key.txtとvalue.txtで保存しました')
print('-'*40)

```
※　dfs[0]は一番目のテーブルのこと
※　.loc[:,['項目名']]で、その項目のみtxtファイルへ保存できる。
※　to_csv()にsep=" “を追加するとtxtファイルとして保存できる。
※　to_csv()に index=Falseを追加するとインデックスNoを削除してtxtファイルへ保存できる。

### □ key.txtとvalue.txtをファイルから呼び出しlistに格納
```python:ioc.py
# key.txtとvalue.txtをファイルから呼び出しlistに格納
with open('key.txt', 'r') as f:
    key = f.read().split('\n')
    ln01 = len(key)             # 要素数を調べる
    
with open('value.txt', 'r') as f:
    value = f.read().split('\n')
    ln02 = len(value)             # 要素数を調べる
 
```

### □ ZIP関数でまとめて辞書に変換
```python:ioc.py
# key.txtを並べたリストとvalue.txtを並べたリストを、ZIP関数でまとめて辞書に変換
ioc = dict(zip(key,value))
```

### □ 繰り返し処理を行うprogramを続けて記述
```python:ioc.py
# 繰り返し処理
a = 0
while True:
    ans = int(input('検索しますか？ YES = 1, NO = 9：'))
    print('')
    if ans == 1:
        # 要素数が不一致の場合表示する
        if ln01 > ln02:
            print(f'要素数はvalueが{ln02-ln01}要素過小で不一致です。')

        elif ln01 < ln02:
            print(f'要素数はkeyが{ln01-ln02}要素過小で不一致です。')
    
        # 例外処理で中断を排除
        try:
            symbol = input('調べたい国記号？（大文字）：')
            print('-'*40)
    
            print(f'国記号[{symbol}] = {ioc[symbol]}')
            print('='*40)
        except KeyError:
            print('ローマ字の大文字３桁で入力してください。')
            print('または、ioc記号が存在しません。')
        finally:
            print('終了します。')
            print('')
    elif ans == 9:
        print('終了します。')
        print('')
        break
    else:
        print('１もしくは９を入力してください。')
        a = 0
    
```

以上で完成です。



```python
# ioc国記号から国名を調べるprogram
import pandas as pd
import requests

# wikipediaの「IOCコード一覧」のページからコード一覧を取得
url = 'https://ja.wikipedia.org/wiki/IOCコード一覧'
# 注１の'UnicodeEncodeError'が出るためrequestsで読み込んだ上でpandasに渡す
r = requests.get(url)
# 引数 match:文字列を指定するとその文字列が含まれる表のみ取得できる
dfs = pd.read_html(r.content, match='コード', header=0)

# key.txtファイル(ioc国記号)とvalue.txtファイル(国名)を同じdirectoryに保存
# to_csv()にsep=" "を追加するとtxtファイルとして保存できる
print()
print('---------txtファイルとして保存----------')
# 国コードを保存
dfs[0].loc[:,['コード']].to_csv('key.txt', sep=" ", index=False)
# 国名を保存
dfs[0].loc[:,['IOC承認国・地域・団体']].to_csv('value.txt', sep=" ", index=False)
print('key.txtとvalue.txtで保存しました')
print('-'*40)

# key.txtとvalue.txtをファイルから呼び出しlistに格納
with open('key.txt', 'r') as f:
    key = f.read().split('\n')
    ln01 = len(key)             # 要素数を調べる
    # print(f'key={ln01}')
    
with open('value.txt', 'r') as f:
    value = f.read().split('\n')
    ln02 = len(value)             # 要素数を調べる
    # print(f'value={ln02}')
 
# key.txtを並べたリストとvalue.txtを並べたリストを、ZIP関数でまとめて辞書に変換
ioc = dict(zip(key,value))

# 繰り返し処理
a = 0
while True:
    ans = int(input('検索しますか？ YES = 1, NO = 9：'))
    print('')
    if ans == 1:
        # 要素数が不一致の場合表示する
        if ln01 > ln02:
            print(f'要素数はvalueが{ln02-ln01}要素過小で不一致です。')

        elif ln01 < ln02:
            print(f'要素数はkeyが{ln01-ln02}要素過小で不一致です。')
    
        # 例外処理で中断を排除
        try:
            symbol = input('調べたい国記号？（大文字）：')
            print('-'*40)
    
            print(f'国記号[{symbol}] = {ioc[symbol]}')
            print('='*40)
        except KeyError:
            print('ローマ字の大文字３桁で入力してください。')
            print('または、ioc記号が存在しません。')
        finally:
            print('終了します。')
            print('')
    elif ans == 9:
        print('終了します。')
        print('')
        break
    else:
        print('１もしくは９を入力してください。')
        a = 0
```