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

求助:Python实现仅支持文本不加载图片的Web代理问题修复

修复你的Web代理服务器:拦截图片资源并正确转发文本请求

看起来你的代理目前有几个关键问题导致图片请求处理异常,同时也没实现拦截图片的核心需求。咱们一步步来修复:

首先分析现有代码的问题

  • 变量名错误:CLIENT.accept()应该是client.accept()(你定义的socket对象是小写的client),这个错误会直接导致代理无法接受连接。
  • 硬编码目标主机:所有GET请求都被转发到images.mid-day.com,这意味着像gaia.cs.umass.edu的文本请求也会被错误发送到图片服务器,你测试时能看到文本大概率是浏览器缓存的原因。
  • 未实现图片拦截逻辑:代码完全没有判断请求的资源类型,自然无法阻止图片加载。
  • 异常处理过于宽泛:except:会掩盖所有错误,比如连接失败、解析错误等,不利于排查问题。

修复后的代码实现

下面是修改后的代码,实现了解析请求目标主机、拦截图片资源、正确转发文本请求的功能:

from socket import *
import re

def is_image_request(request):
    # 匹配常见图片后缀的请求路径
    image_pattern = re.compile(r'\.(jpg|jpeg|png|gif|bmp|webp)$', re.IGNORECASE)
    lines = request.split('\n')
    if lines:
        first_line = lines[0].strip()
        if first_line.startswith('GET'):
            path = first_line.split(' ')[1]
            return image_pattern.search(path) is not None
    return False

def get_host_from_request(request):
    # 从请求头中提取Host字段
    lines = request.split('\n')
    for line in lines:
        if line.strip().lower().startswith('host:'):
            return line.strip().split(':', 1)[1].strip()
    # 如果没有Host字段,尝试从请求路径解析(兼容HTTP/1.0)
    first_line = lines[0].strip()
    if first_line.startswith('GET'):
        url_parts = first_line.split(' ')[1].split('/')
        if len(url_parts) >= 3:
            return url_parts[2]
    return None

proxy_port = 8880
server_socket = socket(AF_INET, SOCK_STREAM)
server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  # 允许端口复用,避免重启报错
server_socket.bind(("", proxy_port ))
server_socket.listen(10)
print(f"代理服务器已启动,监听端口 {proxy_port}...")

while True:
    client_connection, client_address = server_socket.accept()
    print(f"接收到来自 {client_address} 的连接")
    
    try:
        request = client_connection.recv(102400).decode('utf-8', errors='ignore')
        if not request:
            client_connection.close()
            continue
        
        if request.startswith("GET"):
            # 检查是否是图片请求,如果是则返回403拒绝
            if is_image_request(request):
                print("拦截图片请求")
                response = "HTTP/1.1 403 Forbidden\r\nContent-Length: 0\r\n\r\n"
                client_connection.send(response.encode())
                client_connection.close()
                continue
            
            # 解析目标主机
            host = get_host_from_request(request)
            if not host:
                print("无法解析请求的主机")
                client_connection.close()
                continue
            
            # 连接目标服务器并转发请求
            web_socket = socket(AF_INET, SOCK_STREAM)
            web_socket.connect((host, 80))
            web_socket.send(request.encode())
            
            # 循环接收服务器响应,确保完整转发给客户端
            while True:
                reply = web_socket.recv(102400)
                if not reply:
                    break
                client_connection.send(reply)
            
            web_socket.close()
        client_connection.close()
    except Exception as e:
        print(f"处理请求时出错: {str(e)}")
        client_connection.close()

server_socket.close()

关键修改说明

  1. 变量名修正:把错误的CLIENT.accept()改成server_socket.accept()(同时将socket对象重命名为server_socket,语义更清晰)。
  2. 图片拦截逻辑:新增is_image_request函数,通过正则匹配请求路径中的图片后缀,匹配到则返回403拒绝请求,直接阻止图片加载。
  3. 动态解析目标主机:新增get_host_from_request函数,从请求头的Host字段提取目标主机,确保不同的请求转发到对应的服务器,不再硬编码固定主机。
  4. 完整响应转发:循环接收服务器的响应数据,避免大响应被截断,保证文本内容完整显示。
  5. 精准异常处理:捕获具体Exception并打印错误信息,方便排查连接、解析等环节的问题。
  6. 端口复用设置:添加setsockopt(SOL_SOCKET, SO_REUSEADDR, 1),避免重启代理时出现端口被占用的错误。

测试验证

  1. 启动代理服务器,在Chrome中设置代理为127.0.0.1:8880。
  2. 访问http://gaia.cs.umass.edu/wireshark-labs/HTTP-wireshark-file1.html,应该能正常显示文本内容。
  3. 访问http://images.mid-day.com/images/2017/feb/15-salman-khan.jpg,浏览器会显示403禁止访问,图片无法加载,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:29:43