Python遍历IP列表调用geoip2库时的异常处理实现(解决IP不在库中程序中断问题)
GeoIP列表遍历中断问题排查与修正
核心问题定位
- 异常捕获类型完全错位:当前代码仅设置捕获
ValueError类异常,但geoip2库在查询IP不在数据库时,抛出的专属异常为geoip2.errors.AddressNotFoundError,这类异常不在捕获范围内,因此会直接向上抛出中断整个程序。 - 结果存储逻辑缺陷:当前代码用单个
response变量存储查询结果,每次循环都会覆盖上一次的取值,最终仅能保留最后一次遍历的结果,完全丢失了前面所有IP的查询记录,不符合全量遍历的预期。 - 变量未定义风险:如果遍历的第一个IP就触发异常,try块内的
response变量从未完成赋值,循环外的print(response)和return response会额外触发NameError报错。 - 冗余无效代码:循环体内的
end占位语句无实际运行作用,属于代码编写时的笔误。
可实现全量遍历的修正方案
调整逻辑后,程序碰到未收录的IP时会直接跳过、打印提示,不会中断遍历流程,直到走完ipSrcList里的所有条目,核心调整点包括:
- 导入geoip2库对应的未找到地址的异常类,将其加入try-except的捕获范围
- 提前定义空列表存储所有IP的查询结果,每次查询成功就把对应条目追加进列表,避免覆盖丢失
- 所有遍历操作完成后,再统一返回收集到的全量有效结果
- 遍历结束后主动关闭geoip2的数据库读取对象,避免内存占用
修正后的完整代码:
import geoip2.database from geoip2.errors import AddressNotFoundError def getGeoIp(ipSrcList): # 初始化结果存储列表,避免单个变量覆盖丢失记录 query_result = [] reader = geoip2.database.Reader('./GeoLite2-City.mmdb') for ip in ipSrcList: try: response = reader.city(str(ip)) # 查询成功就把IP和对应地理信息存入列表 query_result.append({"ip": ip, "geo_info": response}) # 捕获IP未在数据库中找到的异常 except AddressNotFoundError: print(f'{ip} 未在GeoIP数据库中找到对应记录') # 捕获IP格式非法的异常 except ValueError: print(f'{ip} 格式非法,无法完成查询,已跳过') # 全部遍历完成后统一输出统计信息 print(f'全量遍历完成,共获取到{len(query_result)}条有效IP地理信息记录') # 关闭数据库读取连接,释放资源 reader.close() return query_result
运行效果说明
修正后,遍历过程中无论碰到IP不在数据库、IP格式非法这类可预期异常,都会被对应except块捕获处理,仅打印提示信息后自动进入下一个IP的查询流程,不会触发程序中断,最终返回所有IP中能正常查到地理信息的记录集合。
内容的提问来源于stack exchange,提问作者aroe
相关产品推荐
相关产品推荐

