Python中如何根据IP查询地区?分享一个自制的Python轮子实现
项目地址: https://github.com/459217974/ip2region 从本地数据库查询,速度很快,通过 Tornado IOLoop 可以自动从网上更新数据库。 希望有大佬可以教教我 Cython,昨天刚学的,觉得性能还可以优化一下。
Python中如何根据IP查询地区?分享一个自制的Python轮子实现
3 回复
要基于IP查地区,一个直接的办法是用现成的IP库。我写了个简单的轮子,用到了ip2region这个本地查询方案,比调用外部API更稳定快速。
首先安装依赖:
pip install ip2region
然后是这个轮子的核心代码:
import os
import socket
from ip2region import ip2region
class IPLocator:
def __init__(self, db_path=None):
"""
初始化IP定位器
Args:
db_path: ip2region数据库文件路径,默认使用包内自带的
"""
if db_path is None:
# 使用包自带的数据库
import ip2region
db_path = os.path.join(os.path.dirname(ip2region.__file__), 'data', 'ip2region.db')
if not os.path.exists(db_path):
raise FileNotFoundError(f"IP数据库文件不存在: {db_path}")
self.searcher = ip2region.Ip2Region(db_path)
def query(self, ip):
"""
查询IP对应的地区信息
Args:
ip: 要查询的IP地址
Returns:
dict: 包含国家、省份、城市、ISP等信息
"""
# 验证IP格式
try:
socket.inet_aton(ip)
except socket.error:
raise ValueError(f"无效的IP地址: {ip}")
# 执行查询
result = self.searcher.memorySearch(ip)
# 解析结果
region_info = {
'ip': ip,
'country': result.country,
'region': result.region,
'province': result.province,
'city': result.city,
'isp': result.isp
}
return region_info
def batch_query(self, ip_list):
"""
批量查询IP地址
Args:
ip_list: IP地址列表
Returns:
list: 每个IP的查询结果列表
"""
results = []
for ip in ip_list:
try:
results.append(self.query(ip))
except Exception as e:
results.append({'ip': ip, 'error': str(e)})
return results
def close(self):
"""关闭数据库连接"""
if hasattr(self, 'searcher'):
self.searcher.close()
# 使用示例
if __name__ == "__main__":
# 创建定位器实例
locator = IPLocator()
# 单个IP查询
ip = "8.8.8.8"
result = locator.query(ip)
print(f"查询 {ip}:")
print(f" 国家: {result['country']}")
print(f" 地区: {result['region']}")
print(f" 省份: {result['province']}")
print(f" 城市: {result['city']}")
print(f" ISP: {result['isp']}")
# 批量查询
ips = ["114.114.114.114", "223.5.5.5", "invalid_ip"]
results = locator.batch_query(ips)
print("\n批量查询结果:")
for res in results:
if 'error' in res:
print(f" {res['ip']}: 错误 - {res['error']}")
else:
print(f" {res['ip']}: {res['country']}/{res['city']}")
# 记得关闭连接
locator.close()
这个实现有几个关键点:
- 使用本地数据库,查询速度快且不依赖网络
- 支持单个和批量查询
- 包含基本的IP格式验证
- 结果以字典形式返回,方便进一步处理
ip2region的数据库文件需要定期更新以获取最新的IP分配信息,可以从项目仓库下载最新的ip2region.db文件。
简单说就是:用本地IP库查地区,又快又稳。
建议 readme.md 声明一下你的数据来源
https://github.com/lionsoul2014/ip2region
项目里已经感谢了原项目并且跟原项 owner 说了呢。我也可以详细说一下数据来源,谢谢你提醒

