You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3通过Socket代理发GET请求报400错误,求可行请求格式

解决通过HTTP代理用Socket发送GET请求返回400 Bad Request的问题

你遇到的400错误核心原因是使用HTTP代理访问HTTPS站点时,请求格式完全不符合规范。HTTP代理处理HTTPS请求需要先建立CONNECT隧道,而不是直接发送完整的HTTPS GET请求;即便是访问HTTP站点,GET请求的路径也不能用完整URL,而是要配合Host头使用相对路径。

下面分两种场景给出正确的实现方案:

场景1:通过HTTP代理访问HTTPS站点(比如icanhazip.com)

因为目标站点是HTTPS协议(默认443端口),你需要先通过代理建立加密隧道,再完成SSL握手,最后发送HTTPS请求:

import socket
import ssl

# 代理服务器信息
proxy_host = "xx.xx.xx.xx"
proxy_port = 80
# 目标站点信息
target_host = "icanhazip.com"
target_port = 443

# 1. 先连接到HTTP代理
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((proxy_host, proxy_port))

# 2. 发送CONNECT请求,让代理帮忙建立到目标站点的隧道
connect_request = f"CONNECT {target_host}:{target_port} HTTP/1.1\r\nHost: {target_host}:{target_port}\r\nConnection: close\r\n\r\n"
s.sendall(connect_request.encode("utf-8"))

# 3. 验证隧道是否建立成功
response = s.recv(4096)
if b"200 Connection Established" not in response:
    print(f"隧道建立失败,代理响应:{response.decode('utf-8')}")
    s.close()
    exit()

# 4. 在已建立的隧道上进行SSL握手,创建加密连接
ssl_sock = ssl.wrap_socket(s, server_hostname=target_host)

# 5. 发送标准的HTTPS GET请求(此时路径用相对路径/即可)
get_request = f"GET / HTTP/1.1\r\nHost: {target_host}\r\nConnection: close\r\n\r\n"
ssl_sock.sendall(get_request.encode("utf-8"))

# 6. 接收并打印响应内容
res = ssl_sock.recv(10000)
while len(res) > 0:
    print(res.decode("utf-8"))
    res = ssl_sock.recv(10000)

# 关闭连接
ssl_sock.close()

场景2:通过HTTP代理访问HTTP站点

如果目标是普通HTTP站点(比如http://example.com),不需要建立隧道,直接发送带Host头的相对路径请求即可:

import socket

proxy_host = "xx.xx.xx.xx"
proxy_port = 80
target_host = "example.com"

s = socket.socket()
s.connect((proxy_host, proxy_port))

# 正确的请求格式:GET + 相对路径 + 协议版本,加上Host头,最后用空行结束请求
get_request = f"GET / HTTP/1.1\r\nHost: {target_host}\r\nConnection: close\r\n\r\n"
s.sendall(get_request.encode("utf-8"))

# 接收并打印响应
res = s.recv(10000)
while len(res) > 0:
    print(res.decode("utf-8"))
    res = s.recv(10000)

s.close()

原代码报错的根本原因

你的原代码直接发送了GET https://icanhazip.com HTTP/1.0\r\n,这完全不符合HTTP代理的请求规则:

  • 对于HTTP代理处理HTTP请求的场景,GET的参数应该是目标URL的路径部分(比如/),必须通过Host头告诉代理目标主机是谁。
  • 对于HTTPS请求,必须先通过CONNECT请求让代理建立到目标服务器443端口的隧道,之后才能在隧道内进行HTTPS加密通信。

内容的提问来源于stack exchange,提问作者Hasyar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:00:20