首先要介绍一家公司,总部位于波士顿和马萨诸塞州的 MaxMind 公司成立于2002年,在提供几何定位和在线欺诈工具方面处于领先地位,主要提供以下两项服务:
为啥要介绍这家公司呢?因为他们除了 GeoIP 这个付费服务,另外还提供可以 免费 在 本地部署 的 GeoLite2 离线 数据库,可以让我们在不使用第三方接口的情况,解析 IP 地址的地理位置数据。
需要一个注册 MaxMind 账户才能下载 GeoLite2 免费地理位置数据文件。注册时除了 “邮箱” 需要认真填写(登录时使用 “邮箱” 作为账户名称)之外,其它可以随意,提交注册后 MaxMind 会给你的邮箱发一封邮件,需要点击邮件里的链接以完成注册。
登录后可以打开 GeoLite2 离线数据库下载页面 找到需要的数据库文件:
Database | 包含信息 | 数据库格式 |
---|---|---|
GeoLite2 ASN | 自治域 AS 或者运营商 ISP | MaxMind DB 格式 |
GeoLite2 ASN: CSV Format | IP 地址所属的自治域 AS 或者运营商 ISP | CSV 文件格式 |
GeoLite2 City | IP 地址所在的国家、地区、城市、经纬度和邮政编码等信息 | MaxMind DB 格式 |
GeoLite2 City: CSV Format | IP 地址所在的国家、地区、城市、经纬度和邮政编码等信息 | CSV 文件格式 |
GeoLite2 Country | IP 地址所在的国家和洲 | MaxMind DB 格式 |
GeoLite2 Country: CSV Format | IP 地址所在的国家和洲 | CSV 文件格式 |
两种数据库格式的差别:
下面的例子里,需要下载 GeoLite2 City 数据文件,因为它较其他两者而言,包含的信息更丰富。
使用下面的命令直接安装,或者到 PyPI geoip2 下载文件安装。
pip install geoip2
把下载好的 MaxMind DB 格式 数据库压缩文件解压到项目目录下面,并将数据库的文件路径配置到 geoip2.database.Reader
对象中,再向其传递我们要查询的 IP 地址,如果查询成功,变量 response
将会是一个 geoip2.models.City
类型的数据:
import geoip2.database# 这里只是演示,实际应用时,数据库 Reader 对象应该要重用, 因为它的创建成本很高
with geoip2.database.Reader('GeoLite2-City_20230314/GeoLite2-City.mmdb') as reader:response = reader.city('128.101.101.101')print(f'城市 = {response.city.names["zh-CN"]}')print(f'大洲 = {response.continent.names["zh-CN"]}')print(f'国家 = {response.country.names["zh-CN"]}')print('位置:')print(f'---- 精度半径 = {response.location.accuracy_radius}')print(f'---- 纬度 = {response.location.latitude}')print(f'---- 经度 = {response.location.longitude}')print(f'---- 时区 = {response.location.time_zone}')print(f'邮政编码 = {response.postal.code}')print(f'注册国家 = {response.registered_country.names["zh-CN"]}')print('地区细分:')for subdivision in response.subdivisions:print(f'.... {subdivision.names["zh-CN"]}')
执行上面的代码,会输出下面的内容:
城市 = 明尼阿波利斯
大洲 = 北美洲
国家 = 美国
位置:
---- 精度半径 = 10
---- 纬度 = 44.9402
---- 经度 = -93.2188
---- 时区 = America/Chicago
邮政编码 = 55406
注册国家 = 美国
地区细分:
.... 明尼苏达州
跑通之后可以全面的看一下 geoip2.models.City
类型的 response
变量中,包含哪些数据:
geoip2.models.City({'city': {'geoname_id': 5037649,'names': {'de': 'Minneapolis','en': 'Minneapolis','es': 'Mineápolis','fr': 'Minneapolis','ja': 'ミネアポリス','pt-BR': 'Minneapolis','ru': 'Миннеаполис','zh-CN': '明尼阿波利斯'}},'continent': {'code': 'NA','geoname_id': 6255149,'names': {'de': 'Nordamerika','en': 'North America','es': 'Norteamérica','fr': 'Amérique du Nord','ja': '北アメリカ','pt-BR': 'América do Norte','ru': 'Северная Америка','zh-CN': '北美洲'}},'country': {'geoname_id': 6252001,'iso_code': 'US','names': {'de': 'Vereinigte Staaten','en': 'United States','es': 'Estados Unidos','fr': 'États Unis','ja': 'アメリカ','pt-BR': 'EUA','ru': 'США','zh-CN': '美国'}},'location': {'accuracy_radius': 10,'latitude': 44.9402,'longitude': -93.2188,'metro_code': 613,'time_zone': 'America/Chicago'},'postal': {'code': '55406'},'registered_country': {'geoname_id': 6252001,'iso_code': 'US','names': {'de': 'Vereinigte Staaten','en': 'United States','es': 'Estados Unidos','fr': 'États Unis','ja': 'アメリカ','pt-BR': 'EUA','ru': 'США','zh-CN': '美国'}},'subdivisions': [{'geoname_id': 5037779,'iso_code': 'MN','names': {'en': 'Minnesota','es': 'Minnesota','fr': 'Minnesota','ja': 'ミネソタ州','pt-BR': 'Minesota','ru': 'Миннесота','zh-CN': '明尼苏达州'}}],'traits': {'ip_address': '128.101.101.101','prefix_len': 21}},['en'],
)
然后我们还可以利用返回的经纬度信息,去定位 IP 的相对地理位置:
如果遇到错误和异常,可以查看 官方客户端接口 文档。
由于 IP 信息的新增和修改申请每天都在进行,所以免费的 GeoLite2 离线数据库平均每月更新两次,为了保证 IP 查询的准确性,定期更新离线数据库是有必要的(虽然这并不能保证 IP 地址的信息 100% 准确,毕竟这中间有半个月左右的更新延迟)。
最简单但不长久的方式是 手动下载文件 来完成同步更新,所以建议使用 MaxMind 提供的 GeoIP 更新程序 进行自动更新,详情查看 更新 GeoIP 和 GeoLite 数据库 文档。
以 Windows 版本的 GeoIP 更新程序 为例,我们需要提前创建好 C:\ProgramData\MaxMind\GeoIPUpdate
目录,并把下载好的压缩包解压到这个目录下,并同时新建一个 GeoIP
目录:
然后打开 GeoIP.conf
文件,编辑一下自动更新相关的配置:
主要是三个配置:
AccountID
LicenseKey
EditionIDs GeoLite2-City GeoLite2-Country
编辑完成后保存 GeoIP.conf
文件,然后我们就可以运行 geoipupdate.exe
文件,它会执行一段时间,执行完成后,在 GeoIP
目录下,会出现它帮我们下载好的最新版本的数据库文件:
在 Windows 版本下,需要手动执行,而在 Linux 或 Unix 版本上则可以实现自动化更新过程,例如:每周运行两次,每次更新都会通过电子邮件将结果发送给您。具体的实现方式可以查看 运行 GeoIP 更新 文档。
下一篇:Java中的异常