You need to enable JavaScript to run this app. Python基于Socket发HTTP请求时响应HTML出现3-4长度随机干扰串问题
优惠活动
大模型
产品
解决方案
定价
更多

Python基于Socket发HTTP请求时响应HTML出现3-4长度随机干扰串问题

问题定位与修复方案

核心问题根源

你看到的“30d”“20d0”这类所谓的随机字符串,根本不是无意义内容,就是你完全没处理HTTP 1.1分块传输编码,直接把TCP流里的分块长度标记当成HTML正文混进去了。
HTTP 1.1对动态生成的响应,默认不会提前返回固定的Content-Length头,会采用分块模式传输内容。这种模式下的报文结构是:

  • 每个数据块发送前,先跟一行十六进制格式的块长度值,后面跟\r\n
  • 长度标记后面跟对应长度的实际业务内容
  • 所有内容发完后,发一个长度为0的块作为传输结束标记
    你现在的实现是把所有TCP层收到的字节直接拼接,根本没有拆解这些夹杂在正文里的长度标记,所以十六进制的块长度值(比如30d就是十进制781的十六进制,代表后面跟着781字节的实际内容;20d0对应8400字节的块长)就直接混在HTML文本里出现了。
    你的代码里还存在几个连带的逻辑缺陷,会进一步放大这个问题:
  • 你写的正文截断逻辑data[data.find(newline+newline):data.rfind(f"{newline}0{newline}{newline}")]本身就不对,你想找分块传输的结束标记,但全程没有剥离每个块前的长度标记,哪怕找到结束位置,中间的长度值也会全部保留在正文中
  • 每收到一块TCP数据就立刻调用.decode()的逻辑有问题:TCP是面向流的协议,多字节的UTF-8字符经常会被拆到两个不同的接收包里,这种逐块解码的方式很容易把字符解成乱码
  • 5秒超时就直接break的接收退出逻辑不合理:部分响应慢的站点,只要两次数据包的间隔超过5秒,哪怕正文还没传完,你也会直接停止接收,导致内容截断

具体修复方法

  • 先正确解析响应头:定位到头和正文的分割点后,先检查响应头字段,如果存在Transfer-Encoding: chunked,必须走标准的分块解码流程,不能直接把原始流当正文
  • 实现分块解码逻辑:从正文开头循环读取,先读一行十六进制的块长度值,把这行内容(连同后面的\r\n)直接丢弃,再读取对应长度的实际内容拼接成正文,直到读到长度为0的结束块为止
  • 调整字符解码的时机:不要在每收到一段TCP数据时就做解码,要先把所有二进制数据收集完整,等拆完响应头、解码完分块结构之后,再对二进制形式的正文整体做UTF-8解码,加errors='replace'做兜底,避免跨包的多字节字符解码出错
  • 优化接收退出逻辑:把超时只作为异常兜底的判断条件,当通过分块解码读到传输结束标记时,就主动停止接收循环,不要等超时再退出
  • 可选优化:在构造HTTP请求的时候,主动在请求头里加上Accept-Encoding: identity,可以要求服务器返回未压缩、带明确Content-Length的响应,大幅降低解析复杂度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 20:15:11