我的个人博客网站coolpython.net上线已经有将近两年的时间了,一直都想画一张用户分布的地图,今天终于完成了,效果图如下
本文记录下地图的制作过程
我的网站是用python编写的,使用uwsgi部署,会产生一个名为uwsgi.log的日志文件,记录的内容如下
[pid: 4758|app: 0|req: 62019/129930] 113.110.227.224 () {42 vars in 930 bytes} [Mon Jun 7 16:21:15 2021] GET /static/public/pic/favicon.ico => generated 771 bytes in 1 msecs via sendfile() (HTTP/1.1 200) 8 headers in 306 bytes (0 switches on core 0)
[pid: 4758|app: 0|req: 62020/129931] 223.80.104.104 () {42 vars in 1018 bytes} [Mon Jun 7 16:21:20 2021] GET /python_senior/concurrent/multithreading_lock.html => generated 10024 bytes in 4 msecs (HTTP/1.1 200) 4 headers in 129 bytes (1 switches on core 0)
[pid: 4758|app: 0|req: 62021/129932] 223.80.104.104 () {44 vars in 1097 bytes} [Mon Jun 7 16:21:24 2021] GET /python_primary/python_primary_tutorial.html => generated 10245 bytes in 3 msecs (HTTP/1.1 200) 4 headers in 129 bytes (1 switches on core 0)
使用awk 可以很容易提取出用户的ip地址
cat uwsgi.log | grep "\[pid:" | awk '!a[$5]++{print $5}' > ip.txt
这一步,我使用geoip2,安装方式如下
pip install geoip2
除了需要安装这个库外,还需要下载地图数据,无奈官网上招不到注册的入口,我只好在csdn上花了很多积分下载了一份,免费分享给你
链接:https://pan.baidu.com/s/188Hkgl9p2JRZ_JN9apW8KQ
提取码:2gwi
这个库的使用非常方便
import geoip2.database
client = geoip2.database.Reader('./GeoLite2-City.mmdb')
response = client.city('178.128.196.128')
print(response.country.iso_code) # 国际标准码中的位置
print(response.location.latitude) # 维度
print(response.location.longitude) # 经度
print(response.location.time_zone) # 时区
print(response.city.name) # 城市 Saint Paul
print(response) # 更多参考 ↓
绘制地图,需要使用到matplotlib和mpl_toolkits.basemap, 后者需要使用conda安装
conda install basemap
全部代码如下
import matplotlib
# Anti-Grain Geometry (AGG) backend so PyGeoIpMap can be used 'headless'
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import geoip2.database
client = geoip2.database.Reader('./GeoLite2-City.mmdb')
def generate_map(output, lats=[], lons=[]):
m = Basemap(projection='cyl', resolution='l')
m.bluemarble()
x, y = m(lons, lats)
m.scatter(x, y, s=1, color='#ff0000', marker='o', alpha=0.3)
plt.savefig(output, dpi=300, bbox_inches='tight')
def read_ip():
ip_lst = []
with open('ip.txt')as f:
for line in f:
ip_lst.append(line.strip())
return ip_lst
def geoip_lat_lon(ip_lst):
lats, lons = [], []
for ip in ip_lst:
try:
response = client.city(ip)
except:
continue
lats.append(response.location.latitude)
lons.append(response.location.longitude)
return lats, lons
def run():
ip_lst = read_ip()
lats, lons = geoip_lat_lon(ip_lst)
generate_map('web.png', lats, lons)
run()
观察地图,有一点让我感到惊讶,访问我网站的用户中,有很多是在国外的,难不成都是留学生。
QQ交流群: 211426309