Python3 通过 IP 地址定位地理位置

一般通过 IP 地址定位地理位置的方式有两种,在线 Open API 和 本地离线 SDK

在线 Open API 有很多,国内的就有百度地图、新浪、淘宝等等。

离线 SDK 也有不少,其中最出名的当属 GeoLite2

这些 IP 地址定位地理位置的数据丰富度、数据准确率、查询速度等相关测试已经有知乎大神测试过了:IP信息解析和地理定位,以及免费GeoLite2-City.mmdb的使用教程

在线的 Open API 比较简单,而且都有文档可以参考,本文将重点介绍离线 GeoLite2 库的使用。

GeoLite2 官方 GitHubhttps://github.com/maxmind/GeoIP2-python#database-usage 已经给出示例,除了代码还需要下载一个城市数据库 GeoLite2-City.mmdb

现在这个库貌似已经不在免费了,有人收藏了免费的还可以使用。如果这个地址打不开就通过本地址下载。

一切准备妥当之后就可以愉快的写代码了:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

from geoip2 import database


def main(ip):

    with database.Reader('GeoLite2-City.mmdb') as reader:

        response = reader.city(ip)

        print(f'全量数据:\t\t{response}')

        print(f'国家编码:\t\t{response.country.iso_code}')
        print(f'国家英文名称:\t{response.country.name}')
        print(f'国家中文名称:\t{response.country.names.get("zh-CN")}')

        print(f'州/省编码:\t\t{response.subdivisions.most_specific.iso_code}')
        print(f'州/省英文名称:\t{response.subdivisions.most_specific.name}')
        print(f'州/省中文名称:\t{response.subdivisions.most_specific.names.get("zh-CN")}')

        print(f'城市英文名称:\t{response.city.name}')
        print(f'城市中文名称:\t{response.city.names.get("zh-CN")}')
        print(f'城市邮编:\t\t{response.postal.code}')
        print(f'城市经度:\t\t{response.location.longitude}')
        print(f'城市纬度:\t\t{response.location.latitude}')

        print('-'*50)


if __name__ == '__main__':
    main('202.108.22.5')
    main('100.8.11.58')

运行结果:

全量数据:		geoip2.models.City({'city': {'geoname_id': 1816670, 'names': {'de': 'Peking', 'en': 'Beijing', 'es': 'Pekín', 'fr': 'Pékin', 'ja': '北京市', 'pt-BR': 'Pequim', 'ru': 'Пекин', 'zh-CN': '北京'}}, 'continent': {'code': 'AS', 'geoname_id': 6255147, 'names': {'de': 'Asien', 'en': 'Asia', 'es': 'Asia', 'fr': 'Asie', 'ja': 'アジア', 'pt-BR': 'Ásia', 'ru': 'Азия', 'zh-CN': '亚洲'}}, 'country': {'geoname_id': 1814991, 'iso_code': 'CN', 'names': {'de': 'China', 'en': 'China', 'es': 'China', 'fr': 'Chine', 'ja': '中国', 'pt-BR': 'China', 'ru': 'Китай', 'zh-CN': '中国'}}, 'location': {'accuracy_radius': 500, 'latitude': 39.9288, 'longitude': 116.3889, 'time_zone': 'Asia/Shanghai'}, 'registered_country': {'geoname_id': 1814991, 'iso_code': 'CN', 'names': {'de': 'China', 'en': 'China', 'es': 'China', 'fr': 'Chine', 'ja': '中国', 'pt-BR': 'China', 'ru': 'Китай', 'zh-CN': '中国'}}, 'subdivisions': [{'geoname_id': 2038349, 'iso_code': 'BJ', 'names': {'en': 'Beijing', 'fr': 'Municipalité de Pékin', 'zh-CN': '北京市'}}], 'traits': {'ip_address': '202.108.22.5', 'prefix_len': 17}}, ['en'])
国家编码:		CN
国家英文名称:		China
国家中文名称:		中国
州/省编码:		BJ
州/省英文名称:	Beijing
州/省中文名称:	北京市
城市英文名称:		Beijing
城市中文名称:		北京
城市邮编:		None
城市经度:		116.3889
城市纬度:		39.9288
--------------------------------------------------
全量数据:		geoip2.models.City({'city': {'geoname_id': 5102076, 'names': {'en': 'Nutley'}}, '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': 'USA', 'en': 'United States', 'es': 'Estados Unidos', 'fr': 'États-Unis', 'ja': 'アメリカ合衆国', 'pt-BR': 'Estados Unidos', 'ru': 'США', 'zh-CN': '美国'}}, 'location': {'accuracy_radius': 5, 'latitude': 40.8185, 'longitude': -74.1589, 'metro_code': 501, 'time_zone': 'America/New_York'}, 'postal': {'code': '07110'}, 'registered_country': {'geoname_id': 6252001, 'iso_code': 'US', 'names': {'de': 'USA', 'en': 'United States', 'es': 'Estados Unidos', 'fr': 'États-Unis', 'ja': 'アメリカ合衆国', 'pt-BR': 'Estados Unidos', 'ru': 'США', 'zh-CN': '美国'}}, 'subdivisions': [{'geoname_id': 5101760, 'iso_code': 'NJ', 'names': {'en': 'New Jersey', 'es': 'Nueva Jersey', 'fr': 'New Jersey', 'ja': 'ニュージャージー州', 'pt-BR': 'Nova Jérsia', 'ru': 'Нью-Джерси', 'zh-CN': '新泽西州'}}], 'traits': {'ip_address': '100.8.11.58', 'prefix_len': 24}}, ['en'])
国家编码:		US
国家英文名称:		United States
国家中文名称:		美国
州/省编码:		NJ
州/省英文名称:	New Jersey
州/省中文名称:	新泽西州
城市英文名称:		Nutley
城市中文名称:		None
城市邮编:		07110
城市经度:		-74.1589
城市纬度:		40.8185
--------------------------------------------------

呃。。。经过几百条数据测试,发现国内 IP 基本只能到国家这个维度,国外的还好,但是也一般,我需要的最少也要等城市级别的,所有这个解决方案肯定是不满足了,还是老老实实的使用在线 Open API 吧,百度地图开发平台~真香!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值