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

Python socket发HTTP GET请求如何仅存响应正文及优化大文件接收

问题解决指南

核心问题1:去除HTTP响应头仅保存正文

标准HTTP响应结构中,响应头和正文之间通过\r\n\r\n(连续两个回车换行,对应可视化的空行)分隔,仅需要定位到该分隔符的位置,截取之后的内容即为纯正文内容。

核心问题2:大文件接收不全+缓冲区大小疑问

recv(bufsize)的参数是单次调用最多接收的字节数上限,并非必须接收满bufsize才会返回:如果当前TCP缓冲区可用数据小于bufsize,会直接返回现有数据,因此把缓冲区设为500000字节这类较大值,对2000字节的小文件没有任何负面影响。

大文件接收不全的原因是:单次recv最多只能返回bufsize大小的内容,大文件会被拆分为多个TCP包传输,必须循环调用recv才能收全所有内容。另外你使用的HTTP/1.1协议默认开启长连接,服务器发完内容不会主动断开连接,会导致最后recv进入阻塞状态,有两种常见解决思路:

  • 在请求头中添加Connection: close,通知服务器发完响应就主动断开连接,此时recv返回空字节就代表所有内容接收完成
  • 解析响应头里的Content-Length字段,按照指定的长度接收对应字节数的正文,精准度更高

修正后的完整代码

import socket

clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientSocket.connect((host_name, server_port))
# 请求头新增Connection: close,通知服务器发完内容主动断开
request = ("GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n" % (file_name, host_name)).encode()
clientSocket.send(request)

# 循环接收所有响应内容,缓冲区保持4096常用值即可
received_bytes = b''
while True:
    chunk = clientSocket.recv(4096)
    if not chunk:
        break
    received_bytes += chunk
clientSocket.close()

received_msg = received_bytes.decode()

# 定位响应头和正文的分隔符
header_sep = '\r\n\r\n'
sep_pos = received_msg.find(header_sep)

if received_msg.startswith("HTTP/1.1 404 Not Found"):
    print(index + 1, ".", url, "is not found")
else:
    # 截取分隔符之后的纯正文内容写入文件
    content = received_msg[sep_pos + len(header_sep):]
    with open(only_file_name, 'w', encoding='utf-8') as received_txt_file:
        received_txt_file.write(content)

补充说明

如果遇到乱码问题,可以根据响应头Content-Type字段里的charset参数,调整decode和文件写入时的编码格式即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 15:24:03