0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2021-09-02

概要

パラリンピックを見ていて、国記号がどの国かわからないことが多かったので、検索programを作るために、初めてpandasを使ってみた。
承認国の追加・削除があっても、常に変更に対応するため、wikipediaからスクレイピングすることとした。

インストールの実施

まず、手始めに肝心のpandasのインストールをpipで実施

% pip install pandas

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

% pip install lxml html5lib

programの記述

pandasとrequestsをインポートする。
通常requestsは使わないが、'UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-12: ordinal not in range(128)’のエラーが出るためrequestsを咬ませることで解決した。

ioc.py
import pandas as pd
import requests

□ wikipediaの「IOCコード一覧」のページからコード一覧を取得

ioc.py
# wikipediaの「IOCコード一覧」のページからコード一覧を取得
url = 'https://ja.wikipedia.org/wiki/IOCコード一覧'
# 注1の'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をテキストファイルに保存します。

□ 国コード並びに国名を保存を保存

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に格納

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関数でまとめて辞書に変換

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

□ 繰り返し処理を行うprogramを続けて記述

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('ローマ字の大文字3桁で入力してください。')
            print('または、ioc記号が存在しません。')
        finally:
            print('終了します。')
            print('')
    elif ans == 9:
        print('終了します。')
        print('')
        break
    else:
        print('1もしくは9を入力してください。')
        a = 0
    

以上で完成です。

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

# wikipediaの「IOCコード一覧」のページからコード一覧を取得
url = 'https://ja.wikipedia.org/wiki/IOCコード一覧'
# 注1の'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('ローマ字の大文字3桁で入力してください。')
            print('または、ioc記号が存在しません。')
        finally:
            print('終了します。')
            print('')
    elif ans == 9:
        print('終了します。')
        print('')
        break
    else:
        print('1もしくは9を入力してください。')
        a = 0
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?