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

Python调用YouTube API获取评论时JSON响应损坏致解析失败

解决YouTube API响应中JSON字段被换行拆分导致解析失败的问题

问题根源

直接用原生Socket处理HTTPS请求时,大概率是以下两个原因导致JSON损坏:

  • 分块传输编码未处理:YouTube API的响应默认采用分块传输,每个数据块开头有十六进制的大小标记,结尾带\r\n,如果直接拼接所有接收的数据,这些标记和换行会混入JSON内容。
  • 数据接收不完整/拼接错误:Socket的recv()是按缓冲区返回数据,多次接收后如果没正确分离响应头和响应体,会把响应头的换行符错误带入JSON体,导致字段值被拆分。

具体修复方案

1. 正确处理HTTPS连接与请求

原生Socket直接连443端口传输的是明文,必须用SSL包装才能解密HTTPS数据,否则接收的是乱码,看似换行拆分实际是解密失败:

import socket
import ssl
import json

# 创建Socket并包装SSL层
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(sock)
ssl_sock.connect(("www.googleapis.com", 443))

# 构造符合规范的YouTube API GET请求
request = (
    "GET /youtube/v3/commentThreads?part=snippet&videoId=你的视频ID&key=你的API密钥 HTTP/1.1\r\n"
    "Host: www.googleapis.com\r\n"
    "Connection: close\r\n"
    "\r\n"
)
ssl_sock.send(request.encode("utf-8"))

2. 完整接收并解析HTTP响应

不要直接拼接所有recv()数据,先分离响应头和响应体,再处理分块编码:

def receive_and_parse_response(ssl_sock):
    response = b""
    # 循环接收所有数据直到连接关闭
    while True:
        chunk = ssl_sock.recv(4096)
        if not chunk:
            break
        response += chunk

    # 分离响应头和响应体(按HTTP标准分隔符\r\n\r\n拆分)
    header_split = response.find(b"\r\n\r\n")
    if header_split == -1:
        raise ValueError("无效的HTTP响应格式")
    
    headers = response[:header_split].decode("utf-8")
    body = response[header_split+4:]

    # 处理分块传输编码
    if "Transfer-Encoding: chunked" in headers:
        decoded_body = b""
        remaining_data = body
        while remaining_data:
            # 读取块大小(十六进制转十进制)
            size_end = remaining_data.find(b"\r\n")
            if size_end == -1:
                break
            chunk_size = int(remaining_data[:size_end], 16)
            if chunk_size == 0:
                break
            # 提取块内容并跳过结尾的\r\n
            decoded_body += remaining_data[size_end+2 : size_end+2+chunk_size]
            remaining_data = remaining_data[size_end+2+chunk_size+2:]
        return decoded_body.decode("utf-8")
    else:
        # 非分块响应直接解码返回
        return body.decode("utf-8")

# 获取处理后的响应体
response_body = receive_and_parse_response(ssl_sock)
ssl_sock.close()

# 解析JSON
try:
    data = json.loads(response_body)
    print("JSON解析成功")
except json.JSONDecodeError as e:
    print(f"解析失败:{e}")
    print("损坏的响应片段:", response_body[:500])

3. 容错处理(针对已出现的换行拆分)

如果仍有偶发的字段内换行,可以在解析前清除双引号内的多余换行:

import re

# 匹配双引号内的换行并移除
cleaned_body = re.sub(r'(?<=")([^"]*)\n([^"]*)(?=")', r'\1\2', response_body)

try:
    data = json.loads(cleaned_body)
except json.JSONDecodeError as e:
    print(f"修复后仍解析失败:{e}")

更简便的替代方案

直接使用requests库,它会自动处理HTTPS、分块传输、数据拼接等所有细节,避免原生Socket的繁琐:

import requests

url = "https://www.googleapis.com/youtube/v3/commentThreads"
params = {
    "part": "snippet",
    "videoId": "你的视频ID",
    "key": "你的API密钥"
}

response = requests.get(url, params=params)
data = response.json()
print(data)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:03:19