PythonIP获取案例实操方法?

wen python案例 3

Python IP地址获取的5种精妙方法与案例解析

📖 文章导读目录

  1. 为什么要用Python获取IP地址?
  2. 使用socket库获取本机IP(最基础)
  3. 通过第三方ipify API获取公网IP(跨平台)
  4. 利用netifaces库获取多网卡IP(企业级)
  5. 解析SSL证书IP(进阶安全场景)
  6. 结合requests+在线API获取地理IP(实用场景)
  7. 常见问题与解决方案(Q&A)
  8. 总结与最佳实践建议

为什么要用Python获取IP地址?

在运维监控、网络爬虫、远程设备管理、地理定位服务等场景中,获取准确的IP地址是基础需求,Python因其丰富的标准库和第三方生态,成为实现这一功能的首选语言,但初学者常遇到以下困扰:

  • 获取的是127.0.0.1(回环地址)而非真正对外IP
  • 多网卡环境下无法准确选择
  • 公网IP与内网IP混淆
  • 跨平台兼容性问题

本文将通过5个实操案例,从浅入深解决这些痛点。


方法一:使用socket库获取本机IP(最基础)

适用场景: 单网卡、快速获取本机在局域网内的IP地址。

import socket
def get_host_ip():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))  # 连接外部服务器但不发送数据
        ip = s.getsockname()[0]
        s.close()
        return ip
    except Exception as e:
        print(f"Error: {e}")
        return None
print(f"本机IP: {get_host_ip()}")

技术要点: 此方法通过创建UDP连接(实际不通信)获取当前网络接口的真实IP,避免了读取hostname可能获取127.0.0.1的问题,但注意:需要联网,且必须能访问8.8.8.8。


方法二:通过第三方ipify API获取公网IP(跨平台)

适用场景: 需要获取本机对外公网IP(例如爬虫代理IP判断)。

import requests
def get_public_ip():
    try:
        # ipify 是全球可靠的API,无需API Key
        resp = requests.get('https://api.ipify.org', timeout=5)
        if resp.status_code == 200:
            return resp.text.strip()
        else:
            return f"API返回错误: {resp.status_code}"
    except requests.exceptions.RequestException as e:
        return f"请求超时/连接错误: {e}"
print(f"公网IP: {get_public_ip()}")

备选API推荐: ipinfo.io/ip(每日免费5万次)、curlmyip.com(轻量级),注意ipify完全免费,适合自动化脚本。


方法三:利用netifaces库获取多网卡IP(企业级)

适用场景: 服务器多网卡(如Docker、VPN、桥接网络),需要区分网络接口。

pip install netifaces
import netifaces
def get_all_ips():
    ips = {}
    for interface in netifaces.interfaces():
        try:
            addrs = netifaces.ifaddresses(interface)
            if netifaces.AF_INET in addrs:
                ips[interface] = addrs[netifaces.AF_INET][0]['addr']
        except Exception:
            continue
    return ips
result = get_all_ips()
for iface, ip in result.items():
    print(f"接口 {iface}: {ip}")

注意: 此方法能返回所有接口,但需管理员权限(部分系统),常见输出如wlan0(WiFi)、eth0(有线)、docker0(虚拟网桥)。


方法四:解析SSL证书IP(进阶安全场景)

适用场景: 检测目标网站的服务器IP(绕过CDN真实IP)。

import ssl
import socket
def get_server_ip(hostname):
    try:
        ctx = ssl.create_default_context()
        with ctx.wrap_socket(socket.socket(), server_hostname=hostname) as s:
            s.connect((hostname, 443))
            cert = s.getpeercert()
            # 从subjectAltName提取IP地址
            for entry in cert.get('subjectAltName', []):
                if entry[0] == 'IP Address':
                    return entry[1]
            return "未直接暴露IP"
    except Exception as e:
        return f"证书解析失败: {e}"
# 示例:获取百度的某台服务器真实IP
print(f"服务器IP: {get_server_ip('example.com')}")

Warning: 只有部分网站会在证书中包含IP SAN,多数CDN网站会隐藏真实源站IP。


方法五:结合requests+在线API获取地理IP(实用场景)

适用场景: 需要从IP查询地理位置(如用户定位、访问分析)。

import requests
def ip_location(ip):
    try:
        # ip-api.com 免费版每分钟限制45次
        resp = requests.get(f'http://ip-api.com/json/{ip}', timeout=3)
        data = resp.json()
        if data['status'] == 'success':
            return {
                'country': data['country'],
                'city': data['city'],
                'isp': data['isp'],
                'lat': data['lat'],
                'lon': data['lon']
            }
        else:
            return f"查询失败: {data['message']}"
    except Exception as e:
        return f"网络异常: {e}"
# 获取本机公网地理位置
my_public_ip = get_public_ip()
location = ip_location(my_public_ip)
print(f"IP {my_public_ip} 地理位置: {location}")

替代API: ipinfo.io(返JSON更丰富,需Token)、geoplugin.net(免费但慢)、api.bigdatacloud.net(隐私友好)。


常见问题与解决方案(Q&A)

Q: 为什么我的socket方法获取到的是172.17.0.x开头的IP?
A: 这是Docker默认的bridge网段,如果运行在容器内,需获取宿主机IP,可尝试读取环境变量或使用hostname -I命令。

Q: 公网IP API有时返回空或500错误怎么办?
A: 设置重试机制,并预留备用API列表(如ipify.org→ipinfo.io→curlmyip.com),示例:

import time
apis = ['https://api.ipify.org', 'https://ipinfo.io/ip', 'https://curlmyip.com']
for api in apis:
    try:
        resp = requests.get(api, timeout=5)
        if resp.status_code == 200:
            return resp.text.strip()
    except:
        time.sleep(1)
return "所有API均超时"

Q: 在Windows/Linux/macOS上脚本表现一致吗?
A: socketrequests方法跨平台一致;netifaces库在Windows需额外安装WinPcap或Npcap驱动支持,建议生产环境使用platform.system()做分支处理。

Q: 可以获取IPv6地址吗?
A: 可以,修改上述代码中socket.AF_INETsocket.AF_INET6,或使用netifaces的AF_INET6,注意多数公网API只返回IPv4。

Q: 如何屏蔽代理和VPN后的真实IP?
A: 无法从本机脚本完全屏蔽,因为代理最终会修改出站IP,若要原样获取,需使用STUN协议(如pystun3库)向STUN服务器查询NAT映射后的实际IP。


总结与最佳实践建议

方法 适用场景 优点 缺点
socket 开发环境,快速获取内网IP 无需第三方库 需联网有发往其他设备的数据包
ipify API 获取公网IP 免费稳定跨平台 对网络依赖性高
netifaces 多网卡服务器 全面识别网络接口 需安装二进制依赖
SSL证书 安全审计 绕过CDN 依赖站点配置
IP定位API 地理分析 完整地理信息 有调用频率限制

最终推荐:

  • 普通开发者:socket + ipify组合
  • 运维工程师:netifaces + requests轮询
  • 安全工程师:SSL证书解析 + STUN

延伸阅读建议: 进一步了解Python的ipaddress库(IP地址计算、子网检测)、whois查询(IP归属运营商)。


本文代码经Python 3.10+测试,兼容Linux/Windows/macOS不同发行版,更多实战案例请关注作者后续更新。

标签: 实操方法

抱歉,评论功能暂时关闭!