
IPアドレス群からワールドヒートマップを作成してみた
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、森田です。
アクセスログの多くには、アクセス元のIPアドレスを含んでいます。
そのIPアドレスを集計し、可視化する方法の1つとしてワールドヒートマップがあります。
本記事では、実際にIPアドレス群からPythonでデータの処理を行い、ワールドヒートマップを行って行きます。
検証環境
- Python 3.8.5
- pandas
- numpy
- geoip2 4.5.0
- pycountry 20.7.3
- folium 0.12.1
使用するデータ
データは下記のようなIPアドレス群を使用します。csvファイルでまとめてあるものとします。

使用ライブラリ
IPアドレスから国を推定するためgeoip2、geoip2で取得できる国名コード変換用にpycountryを使用します。
また、基本的なデータ処理はPandasを用いて行い、ヒートマップはfoliumを使用します。
Pandas、pycountryは、pipコマンドなどでインストールを行います。
pip install pandas pycountry
geoip2(GeoLite2)のインストール
まず、pipコマンドを用いてインストールを行います。
pip install geoip2
geoip2を使用するためには、ファイルのダウンロードなどが必要となります。
こちらよりGeoLite2 Cityのダウンロードを行います。
ダウンロードしたファイルは以下のように使用します。
import geoip2.database
ip = '11.109.10.11'
reader = geoip2.database.Reader('GeoLite2-City.mmdb')
res = reader.city(ip)
print(res.country)
geoip2.records.Country(confidence=None, geoname_id=6252001, is_in_european_union=False, iso_code='US', _locales=['en'], names={'de': 'USA', 'en': 'United States', 'es': 'Estados Unidos', 'fr': 'États Unis', 'ja': 'アメリカ', 'pt-BR': 'EUA', 'ru': 'США', 'zh-CN': '美国'})
Foliumのインストール
Foliumは、Pythonの地理データ可視化ライブラリの1つです。
このライブラリは、Quickstartを見るだけなんとなく使えるほど簡単に使用できるのがとても魅力的です。
こちらの使用には、まずpipでインストールを行います。
pip install folium
その後、地図データの別途ダウンロードが必要ですので、下記コマンドでデータをダウンロードします。
git clone https://github.com/python-visualization/folium.git
ワールドマップの場合は、examples/data/world-countries.jsonのデータを使用します。
データ前処理
ライブラリ・必要ファイルが準備できたので、先ほどのIPアドレスCSVファイルを国ごとでグループ化していきます。
まず、geoip2で取得できる国名コードがfoliumに対応していないのでpycountryで変換するように関数化します。
import geoip2.database
import pycountry
def country_checker(ipaddress):
try :
reader = geoip2.database.Reader('GeoLite2-City.mmdb')
response = reader.city(ipaddress)
return pycountry.countries.get(alpha_2=response.country.iso_code).alpha_3
except:
return None
この関数をそれぞれのIPアドレスに適用させ、country列を新規で作成していきます。
df["country"] = df["IP"].apply(country_checker)
国ごとでグループ化するため、counts列を追加します。
df["counts"] = 1
では、国ごとでグループ化を行い、countsの合計値を算出します。
import numpy as np
df2 = df[["country", "counts"]].groupby('country').agg(np.sum)
counts country AUS 273 BRA 37 FRA 110 GBR 116 IDN 151 ITA 76 JPN 119 SGP 67 USA 474
最後に、foliumで可視化させる場合、国コードを列データとして渡すので、indexから新規にiso_code列を作成しておきます。
df2['iso_code'] = df2.index
ワールドマップ作成
では、最後にfoliumで可視化を行います。
import folium
# world map import
m = folium.Map(location=[50, 0], zoom_start=1)
geojson = "./folium/examples/data/world-countries.json"
# visualization
folium.Choropleth(
geo_data=geojson,
name='choropleth',
data=df2, # Input DataFrame
columns=['iso_code', 'counts'],
key_on='feature.id',
fill_color='OrRd',
fill_opacity=0.7,
line_opacity=1,
legend_name='IP Adress Access'
).add_to(m)
m.save("world.html")
このようにして作成されたワールドマップは以下となります。
いい感じで上手く可視化されました!
まとめ
今回は、GeoLite2、Foliumなどを用いて、IPアドレスごとのアクセスをヒートマップにしてみましたが、ドキュメントを少し読むだけで作れたのでとても簡単でした!
ぜひ、アクセスログをお持ちの方は、IPアドレスを抽出し、ワールドヒートマップを作ってみてはいかがでしょうか?
今回のコード・ファイル
参考
GeoLite2でサクッとできるIPアドレスの国判定
Folium 0.12.1 documentation Quickstart






