当前位置: 首页 > ds >正文

【运维实战】Python打造基于免费API的IP地址归属地批量查询工具!

打造基于免费API的IP地址归属地批量查询工具

项目简介

基于Python的IP地址归属地免费批量查询工具,可以快速查询大量IP地址的地理位置和网络信息,支持国际和国内API双查询模式,结果自动保存为Excel文件。

效果展示

IP地址        国家      地区      城市      ISP               AS             查询状态
8.8.8.8      美国      加利福尼亚 山景城    Google LLC        AS15169 Google  success
1.1.1.1      澳大利亚  新南威尔士 悉尼      Cloudflare, Inc.  AS13335         success
114.114.114.114 中国    江苏省    南京市    南京信风网络科技   AS9808          success
223.5.5.5     中国      北京市    北京市    阿里云计算有限公司 AS37963         success
101.226.4.6   中国      上海市    上海市    中国电信          AS4812          success
218.30.118.6  中国      北京市    北京市    北京电信通        AS23724         success
61.135.169.121 中国     北京市    北京市    百度网讯科技      AS55990         success
119.29.29.29  中国      广东省    广州市    腾讯云计算       AS45090         success
202.96.134.33 中国      广东省    广州市    中国电信          AS4134          success
202.96.128.86 中国      广东省    广州市    中国电信          AS4134          success
202.96.128.166 中国     广东省    广州市    中国电信          AS4134          success
202.96.128.68 中国      广东省    广州市    中国电信          AS4134          success

基础环境要求

  • Python 3.6+

  • 依赖库:

    • requests (用于API请求)

    • openpyxl (用于生成Excel文件)

    • concurrent.futures (用于并发查询)

安装依赖:

pip install requests openpyxl

关键代码解析

1. IP地址验证

def is_valid_ip(ip: str) -> bool:"""验证IP地址格式是否有效"""try:parts = ip.split('.')iflen(parts) != 4:returnFalsefor part in parts:ifnot part.isdigit() ornot0 <= int(part) <= 255:returnFalsereturnTrueexcept:return False

2. IP查询核心逻辑

def lookup_ip(ip: str) -> Dict:"""查询单个IP地址的归属地信息"""# 包含缓存机制、重试逻辑和国际/国内API双查询模式# ...

3. 批量查询功能

def get_ip_location_batch(ip_list: List[str], max_workers: int = 5) -> List[Dict]:"""批量查询IP地址归属地"""# 使用线程池实现并发查询# ...

重要第三方库

1. requests

用于发送HTTP请求到IP查询API,支持超时设置和异常处理。

2. openpyxl

用于将查询结果生成格式化的Excel文件,支持自动调整列宽和样式设置。

API介绍

1. ip-api.com国际API

  • 免费查询限制:45次/分钟(非商业用途)

  • 返回数据格式:JSON

  • 包含字段:国家、地区、城市、ISP、AS号等

  • 使用注意事项:

    • 需要遵守API使用条款

    • 商业用途需要购买专业版

    • 建议添加User-Agent标识

2. 淘宝IP库国内API

  • 免费查询限制:100次/天

  • 返回数据格式:JSON

  • 包含字段:国家、省份、城市、运营商等

  • 使用注意事项:

    • 仅限国内IP查询

    • 需要处理中文编码

    • 建议添加请求间隔避免被封禁

使用说明

  1. 准备一个文本文件(input.txt),每行一个IP地址

  2. 运行命令:

python get_ip_location_batch.py --input input.txt --output result.xlsx
  1. 可选参数:

    • --workers: 设置并发查询线程数(默认5)

测试案例

输入文件示例(input.txt):

8.8.8.8
1.1.1.1
114.114.114.114
223.5.5.5
101.226.4.6
218.30.118.6
61.135.169.121
119.29.29.29
202.96.134.33
202.96.128.86
202.96.128.166
202.96.128.68

运行后生成的Excel文件包含以下信息:

  • IP地址

  • 国家

  • 地区

  • 城市

  • ISP

  • AS

  • 查询状态

示例数据格式(output.xls):

IP地址        国家      地区      城市      ISP               AS             查询状态
8.8.8.8      美国      加利福尼亚 山景城    Google LLC        AS15169 Google  success
1.1.1.1      澳大利亚  新南威尔士 悉尼      Cloudflare, Inc.  AS13335         success
114.114.114.114 中国    江苏省    南京市    南京信风网络科技   AS9808          success
223.5.5.5     中国      北京市    北京市    阿里云计算有限公司 AS37963         success
101.226.4.6   中国      上海市    上海市    中国电信          AS4812          success
218.30.118.6  中国      北京市    北京市    北京电信通        AS23724         success
61.135.169.121 中国     北京市    北京市    百度网讯科技      AS55990         success
119.29.29.29  中国      广东省    广州市    腾讯云计算       AS45090         success
202.96.134.33 中国      广东省    广州市    中国电信          AS4134          success
202.96.128.86 中国      广东省    广州市    中国电信          AS4134          success
202.96.128.166 中国     广东省    广州市    中国电信          AS4134          success
202.96.128.68 中国      广东省    广州市    中国电信          AS4134          success

完整代码

import requests
import concurrent.futures
import json
import time
from typing importList, Dict# 使用ip-api.com免费API进行IP查询
IP_API_URL = "http://ip-api.com/json/{ip}?fields=status,message,country,regionName,city,isp,org,as,query"
# 国内IP查询API
CN_API_URL = "https://ip.taobao.com/outGetIpInfo?ip={ip}"# 缓存字典避免重复查询
IP_CACHE = {}defis_valid_ip(ip: str) -> bool:"""验证IP地址格式是否有效"""try:parts = ip.split('.')iflen(parts) != 4:returnFalsefor part in parts:ifnot part.isdigit() ornot0 <= int(part) <= 255:returnFalsereturnTrueexcept:returnFalsedeflookup_ip(ip: str) -> Dict:"""查询单个IP地址的归属地信息"""ifnot is_valid_ip(ip):return {"ip": ip, "error": "Invalid IP address format"}# 检查缓存if ip in IP_CACHE:return IP_CACHE[ip]max_retries = 3retry_delay = 1# 初始重试延迟秒数for attempt inrange(max_retries):try:# 优先使用国际API查询try:response = requests.get(IP_API_URL.format(ip=ip), timeout=5)response.raise_for_status()ifnot response.text.strip():raise ValueError("Empty response from API")data = response.json()if data.get("status") == "success":result = {"ip": ip, "data": data}IP_CACHE[ip] = resultreturn resultelse:raise requests.exceptions.RequestException(data.get("message", "API returned error"))except requests.exceptions.RequestException as e:if"Max retries exceeded"instr(e):# 国际API失败时使用国内API作为备用response = requests.get(CN_API_URL.format(ip=ip), timeout=5)ifnot response.text.strip():raise ValueError("Empty response from API")data = response.json()if data.get("code") == 0:result = {"ip": ip, "data": data.get("data", {})}IP_CACHE[ip] = resultreturn resultelse:raise requests.exceptions.RequestException("国内API请求失败")else:raiseifnot response.text.strip():raise ValueError("Empty response from API")data = response.json()if data.get("status") == "success":result = {"ip": ip, "data": data}IP_CACHE[ip] = resultreturn resultelse:result = {"ip": ip, "error": data.get("message", "Unknown error")}IP_CACHE[ip] = resultreturn resultexcept requests.exceptions.RequestException as e:if attempt == max_retries - 1:result = {"ip": ip, "error": f"API请求失败(尝试{attempt+1}次): {str(e)}"}IP_CACHE[ip] = resultreturn resulttime.sleep(retry_delay * (attempt + 1))except ValueError as e:if attempt == max_retries - 1:result = {"ip": ip, "error": f"JSON解析失败(尝试{attempt+1}次): {str(e)}"}IP_CACHE[ip] = resultreturn resulttime.sleep(retry_delay * (attempt + 1))# 所有尝试都失败result = {"ip": ip, "error": "所有API请求尝试均失败"}IP_CACHE[ip] = resultreturn resultdefget_ip_location_batch(ip_list: List[str], max_workers: int = 5) -> List[Dict]:"""批量查询IP地址归属地"""results = []with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:future_to_ip = {executor.submit(lookup_ip, ip): ip for ip in ip_list}for future in concurrent.futures.as_completed(future_to_ip):results.append(future.result())return resultsdefread_ips_from_file(file_path: str) -> List[str]:"""从文件读取IP列表"""withopen(file_path, 'r') as f:return [line.strip() for line in f if line.strip()]defsave_results_to_file(results: List[Dict], output_file: str):"""将查询结果保存到Excel文件"""from openpyxl import Workbookfrom openpyxl.styles import Font, Alignment, PatternFillwb = Workbook()ws = wb.activews.title = "IP查询结果"# 设置表头样式header_font = Font(bold=True)header_alignment = Alignment(horizontal='center')header_fill = PatternFill(start_color='D3D3D3', end_color='D3D3D3', fill_type='solid')# 写入表头headers = ["IP地址", "国家", "地区", "城市", "ISP", "AS", "状态"]ws.append(headers)# 应用表头样式for cell in ws[1]:cell.font = header_fontcell.alignment = header_alignmentcell.fill = header_fill# 写入数据for result in results:if'data'in result:data = result['data']row = [result['ip'],data.get('country', '未知'),data.get('regionName', '未知'),data.get('city', '未知'),data.get('isp', '未知'),data.get('as', '未知'),"成功"]else:row = [result['ip'], "", "", "", "", "", f"错误: {result.get('error', '未知错误')}"]ws.append(row)# 自动调整列宽for column in ws.columns:max_length = 0column_letter = column[0].column_letterfor cell in column:try:iflen(str(cell.value)) > max_length:max_length = len(str(cell.value))except:passadjusted_width = (max_length + 2) * 1.2ws.column_dimensions[column_letter].width = adjusted_widthwb.save(output_file)if __name__ == "__main__":import argparseparser = argparse.ArgumentParser(description='IP地址归属地批量查询工具')parser.add_argument('--input', required=True, help='包含IP地址列表的输入文件路径')parser.add_argument('--output', required=True, help='查询结果输出文件路径')parser.add_argument('--workers', type=int, default=5, help='并发查询线程数')args = parser.parse_args()print(f"正在从 {args.input} 读取IP地址...")ip_list = read_ips_from_file(args.input)print(f"共读取到 {len(ip_list)} 个IP地址,开始查询...")results = get_ip_location_batch(ip_list, args.workers)print(f"查询完成,正在将结果保存到 {args.output}...")save_results_to_file(results, args.output)print("操作完成!")
http://www.xdnf.cn/news/8252.html

相关文章:

  • 5.0.6 TreeView的使用介绍
  • find-chomd-read-ls和ll的区别
  • Crawl4AI:高效的AI数据抓取工具
  • Spring概念问题详解
  • [C++面试] 基础题
  • springboot 集成kerberos 用户认证 获取域账号
  • 完整改进RIME算法,基于修正多项式微分学习算子Rime-ice增长优化器,完整MATLAB代码获取
  • 【数据结构】 栈和队列
  • 微软全新开源的Agentic Web网络项目:NLWeb,到底是什么 ?
  • 鸿蒙App开发学习路径
  • JAVA|后端编码规范
  • 仿腾讯会议——视频发送接收
  • 计算机发展史
  • 从零基础到最佳实践:Vue.js 系列(7/10):《常用内置 API 与插件》
  • scratch课后一练--事件模块
  • Linux系统编程 | IPC对象---消息队列
  • DeepSeek:开启IT领域人效管理新时代
  • Java-根据路径获取JSON字符串的value值
  • zabbix 常见问题
  • 深入解析JVM垃圾回收器:原理、实践与调优指南
  • 实用重复文件批量处理工具
  • 关于SQL SERVER中round函数的用法和示例
  • 一台机器怎么部署k8s集群
  • React-fiber架构
  • Python可视化设计原则
  • 【424. 替换后的最长重复字符】
  • docker-compose常用命令介绍
  • 已经 上线 Vue 项目 国际化 i18n 中译英
  • OpenCV 图像对象的创建与赋值
  • Apollo10.0学习——planning模块(9)之参数详解一