升级至GeoIP2后缺失Region字段,如何从CityResponse提取?
解决GeoLite2-City.mmdb中从CityResponse提取地区信息的问题
嘿,我之前也踩过这个坑!GeoLite2-City数据库里确实没有直接叫Region的字段,但它把地区(省/州/一级行政区)的信息藏在subdivisions这个结构里了——这就是你要找的内容。
核心原理
GeoIP2的CityResponse对象中,行政区信息都存在subdivisions集合/数组里。这个集合里的元素对应不同层级的行政区(比如国家下的省、省下面的市),绝大多数情况下,第一个元素就是你需要的一级地区(比如中国的省份、美国的州)。
不同语言的实现示例
下面给两个最常用语言的代码片段,你可以直接参考:
Python(使用maxminddb库)
import maxminddb # 打开数据库文件 with maxminddb.open_database('GeoLite2-City.mmdb') as reader: # 获取目标IP的响应数据 response = reader.get('192.168.1.1') # 检查是否存在行政区信息 if 'subdivisions' in response: # 取第一个行政区(一级地区) first_subdivision = response['subdivisions'][0] # 获取英文名称 region_name_en = first_subdivision['names']['en'] # 获取ISO代码(比如CN-SH对应上海,US-TX对应德克萨斯州) region_iso_code = first_subdivision['iso_code'] # 如果需要中文名称,数据库支持的话可以这样取 region_name_zh = first_subdivision['names'].get('zh-CN', '无中文名称') print(f"地区名称:{region_name_zh}({region_name_en}),代码:{region_iso_code}") else: print("该IP未查询到地区信息")
PHP(使用maxmind/geoip2扩展库)
require_once 'vendor/autoload.php'; use GeoIp2\Database\Reader; try { $reader = new Reader('GeoLite2-City.mmdb'); $record = $reader->city('192.168.1.1'); // 检查是否有行政区数据 if (!empty($record->subdivisions)) { $region = $record->subdivisions[0]; echo "地区名称(英文):" . $region->name . "<br>"; echo "地区ISO代码:" . $region->isoCode . "<br>"; // 尝试获取中文名称 $chinese_name = $region->names['zh-CN'] ?? '无中文名称'; echo "地区名称(中文):" . $chinese_name . "<br>"; } else { echo "未查询到该IP的地区信息"; } $reader->close(); } catch (Exception $e) { echo "查询出错:" . $e->getMessage(); }
额外注意事项
- 有些IP(比如小型国家的IP、特殊网段)可能没有细分的地区信息,所以一定要做判空处理,避免抛出空指针或数组越界错误。
- 本地化名称(如中文)需要数据库支持,GeoLite2-City默认包含多种语言的名称,你可以通过对应的语言代码(比如
zh-CN、fr)来获取。 - 如果你需要二级行政区(比如市),可以直接取
subdivisions数组的第二个元素(如果存在的话)。
内容的提问来源于stack exchange,提问作者yoavba
相关产品推荐
相关产品推荐

