本文目录导读:

在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"
注意事项
-
代理服务器:如果网站使用Nginx、Apache等代理,
remote_addr可能显示代理的IP,应优先检查X-Forwarded-For头部。 -
安全性:
X-Forwarded-For可以被伪造,生产环境应考虑:# 限制信任的代理 TRUSTED_PROXIES = ['127.0.0.1', '10.0.0.0/8']
-
IPv6支持:在获取IP时注意处理IPv6地址格式
-
WebSocket:获取方式类似HTTP,但在WebSocket握手阶段获取
选择哪种方式取决于你的应用场景和技术栈,建议在Web应用中使用框架提供的方法并考虑代理情况。