Python案例如何获取客户端IP?

wen python案例 15

本文目录导读:

Python案例如何获取客户端IP?

  1. Flask框架
  2. Django框架
  3. FastAPI框架
  4. 纯Socket/HTTP服务器
  5. 通用函数(适用于任何环境)
  6. 注意事项

在Python中获取客户端IP的方法取决于你使用的框架或场景,以下是常见情况下的实现方式:

Flask框架

from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def get_client_ip():
    # 最简单方式:直接从request.remote_addr获取
    client_ip = request.remote_addr
    # 更可靠的方式(考虑代理情况)
    if request.headers.get('X-Forwarded-For'):
        # X-Forwarded-For可能包含多个IP,第一个是客户端真实IP
        client_ip = request.headers.get('X-Forwarded-For').split(',')[0].strip()
    elif request.headers.get('X-Real-IP'):
        client_ip = request.headers.get('X-Real-IP')
    else:
        client_ip = request.remote_addr
    return f"客户端IP: {client_ip}"
if __name__ == '__main__':
    app.run(debug=True)

Django框架

# 在views.py中
from django.shortcuts import render
def get_client_ip(request):
    # 方法1:直接获取
    ip = request.META.get('REMOTE_ADDR')
    # 方法2:考虑代理
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return render(request, 'index.html', {'ip': ip})
# 或使用工具函数
def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

FastAPI框架

from fastapi import FastAPI, Request
app = FastAPI()
@app.get("/")
async def get_client_ip(request: Request):
    # 直接获取
    ip = request.client.host
    # 考虑代理
    forwarded = request.headers.get("X-Forwarded-For")
    if forwarded:
        ip = forwarded.split(",")[0].strip()
    return {"client_ip": ip}

纯Socket/HTTP服务器

import socket
from http.server import HTTPServer, BaseHTTPRequestHandler
class IPHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        # 获取客户端IP
        client_ip = self.client_address[0]
        # 检查X-Forwarded-For头部
        forwarded = self.headers.get('X-Forwarded-For')
        if forwarded:
            client_ip = forwarded.split(',')[0].strip()
        self.send_response(200)
        self.send_header('Content-type', 'text/plain')
        self.end_headers()
        self.wfile.write(f"Client IP: {client_ip}".encode())
    def log_message(self, format, *args):
        # 自定义日志输出
        print(f"{self.client_address[0]} - {format % args}")
if __name__ == '__main__':
    server = HTTPServer(('0.0.0.0', 8000), IPHandler)
    print('服务器启动在 http://localhost:8000')
    server.serve_forever()

通用函数(适用于任何环境)

import socket
def get_local_ip():
    """获取本机IP地址"""
    try:
        # 方法1:通过连接互联网获取
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        local_ip = s.getsockname()[0]
        s.close()
        return local_ip
    except:
        # 方法2:通过主机名获取
        hostname = socket.gethostname()
        return socket.gethostbyname(hostname)
def get_public_ip():
    """获取公网IP地址"""
    import requests
    try:
        response = requests.get('https://api.ipify.org')
        return response.text.strip()
    except:
        return "无法获取公网IP"

注意事项

  1. 代理服务器:如果网站使用Nginx、Apache等代理,remote_addr可能显示代理的IP,应优先检查X-Forwarded-For头部。

  2. 安全性X-Forwarded-For可以被伪造,生产环境应考虑:

    # 限制信任的代理
    TRUSTED_PROXIES = ['127.0.0.1', '10.0.0.0/8']
  3. IPv6支持:在获取IP时注意处理IPv6地址格式

  4. WebSocket:获取方式类似HTTP,但在WebSocket握手阶段获取

选择哪种方式取决于你的应用场景和技术栈,建议在Web应用中使用框架提供的方法并考虑代理情况。

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