Beautiful Soup Matplotlib pandas Python スクレイピング データ分析 プログラミング

【Python】世界各国の人口データをスクレイピングして取得する

この記事は約8分で読めます。

 

Pythonで世界各国の人口データを取得する

 

先日株価分析に人口データを用いたいと思いまして、pandas-datareaderとかでうまいこと取得できないかなーと色々検索していたのですが、国別にうまく取得できるサイトが中々見つからず苦労していたのですが、先日目途が立ったのでとりあえずまとめてみました。

 

今回は世界経済のネタ帳というサイトからPythonを使ったスクレイピングでアジア各国の人口データとGDPを取得してみます。

 

流れとしては、requestsでスクレイピングしてBeautifulSoupでHTMLから必要なデータを抽出。Pandasで整形してMatplotlibで描画といった感じになります。

 

 

関連記事:PythonでのWebスクレイピングには「requests」がめっちゃ便利という話

 

関連記事:【Python】「Beautiful Soup」でスクレイピングしたhtmlデータを解析する

 

関連記事:【Python】Matplotlibでのグラフ作成の基本をわかりやすく解説する

 

 

 

<実行環境>

  • Windows10
  • Python3.7
  • JupyterLab

 

# ライブラリの呼び出し
import requests
import json
from bs4 import BeautifulSoup
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

def get_tabledata(url='https://ecodb.net/ranking/old/area/A/imf_ngdpd', start=1980, end=2018):
    """
    世界経済のネタ帳からスクレイピングでデータを取得する関数
    url{str} : forでループさせる大元のURL
    start {int/str} : 開始年数(1980年がより前のデータはなさそう)
    end {int/str} : 終了年数(現在の年数-2、前年のデータはURLの仕様が少し違うので、別でスクレピングする必要あり)
    """
    data_dict = {}
    for year in range(start, end):
        # 対象ページのHTMLデータを取得&BS4形式に変換
        res = requests.get(f'{url}_{year}.html')
        data = BeautifulSoup(res.text,'html.parser')
        # htmlの中からtableタグを抽出する
        data_table = data.find('table')
        # テーブルから1列ずつ国名と数値を抜き出す
        country_dict = {}
        for row in range(len(data_table.find_all('tr'))):
            country = data_table.find_all('tr')[row]
            # 最初の1と2はアジア合計と世界合計の列で他とタグが若干異なっているのでIF文で処理
            if row == 1:
                asia_sum_ = country.find('td', class_='value').text.replace(',', '').replace("'", '')
                # 辞書にKEYと値を追加する
                country_dict['アジア合計'] = float(asia_sum_)
            if row == 2:
                world_sum_ = country.find('td', class_='value').text.replace(',', '').replace("'", '')
                # 辞書にKEYと値を追加する
                country_dict['世界合計'] = world_sum_
            # それ以外の国名の列は同じように処理
            else:
                try:
                    # 国名とGDPを取得して辞書に追加していく
                    country_name = country.find('td', class_='name tap').text.replace('\n', '').replace('\xa0', '')
                    gdp = country.find('td', class_='value value_bar_chart').text.replace(',', '')
                    country_dict[country_name] = float(gdp)
                except Exception as e:
                    pass
        # 各年代のアジア各国のデータ数値({国名:数値}の辞書データを辞書の中に追加する
        data_dict[str(year)] = country_dict
    return data_dict


# 関数を実行してデータを取得する
people_data = get_tabledata(url='https://ecodb.net/ranking/old/area/A/imf_lp_', start=1980, end=2018)
gdp_data = get_tabledata(url='https://ecodb.net/ranking/old/area/A/imf_ngdpd_', start=1980, end=2018)

 

 

このコードだとfor文で回しているURLの仕様上で最新の年のデータが取得できません。いずれgitに完成版をアップロードするつもりですが、これでも40年分くらいのデータは集められるので、十分使えると思います。

 

<実行結果>は↓のような感じ

 

 

 

 

これをデータフレームに整形します

 

# アジアの国のリストを作成する
asia_list = list(gdp_data['1980'].keys())

people_dict = {}
gdp_dict = {}

for country in asia_list:
    p_data, g_data = [], []
    for year in people_data.keys():
        try:
            p_data.append(people_data[year][country])
        except:
            p_data.append('NaN')
    people_dict[country] = p_data
    for year in gdp_data.keys():
        try:
            g_data.append(gdp_data[year][country])
        except:
            g_data.append('NaN')
    gdp_dict[country] = g_data


# 辞書からデータフレームに変換する
df_people = pd.DataFrame(people_dict.values(), index=people_dict.keys())
df_people.columns = range(1980, 2018)
df_gdp = pd.DataFrame(gdp_dict.values(), index=gdp_dict.keys())
df_gdp.columns = range(1980, 2018)

# csv出力
df_people.to_csv('asia_population.csv', encoding='SJIS')
df_gdp.to_csv('asia_gdp.csv', encoding='SJIS')

 

 

次はこれをMatplotlibでプロットします。

 

# データをJupyterNotebookでプロットする場合 #
from pylab import rcParams
rcParams['figure.figsize'] = 10, 20

for i in df_gdp.index[2:]:
    try:
        plt.plot(df_gdp.loc[i], label=i)
    except:
        pass
plt.title('アジア各国の年代別GDP推移')
plt.grid(which='both')
plt.legend()
plt.show()

 

 

<実行結果>

 

 

人口とGDP共に中国の伸びがすごいですね(小並感)

他にもインド・インドネシア・タイ・ベトナム辺りも伸びてきています。

 

 

 

関連記事:【Python】CoinGeckoのAPIからビットコイン・アルトコインの価格データを取得する

 

関連記事:【Python】TwitterのAPIを簡単操作できる「Tweepy」の使い方

 

関連記事:【Python】Quandlから上場企業の株価データを取得する

 

関連記事:【Python】pandasで日経平均の株価データをスクレイピングする

 

 

 


プログラミング・スクレイピングツール作成の相談を受け付けています!

クラウドワークス・ココナラ・MENTAなどでPython・SQL・GASなどのプログラミングに関する相談やツール作成などを承っております!

過去の案件事例:

  • Twitter・インスタグラムの自動化ツール作成
  • ウェブサイトのスクレイピングサポート
  • ダッシュボード・サイト作成
  • データエンジニア転職相談

これまでの案件例を見る

キャリア相談もお気軽に!文系学部卒からエンジニア・データサイエンティストへの転職経験をもとに、未経験者がどう進むべきかのアドバイスを提供します。


スポンサーリンク
/* プログラミング速報関連記事一覧表示 */
ミナピピンの研究室

コメント

タイトルとURLをコピーしました