如何正确解析被 HTML 实体编码的嵌套 JSON 字段

技术百科 碧海醫心 发布时间:2026-01-27 浏览:

当 api 返回的 json 中某些字段(如 `child_sku_options`)实际是经过 html 实体编码的 json 字符串时,直接 `json.loads()` 会失败;需先用 `html.unescape()` 还原转义字符,再二次解析。

在调用某些搜索服务(如 SearchSpring)的 API 时,常见一种“伪嵌套 JSON”现象:主响应是合法 JSON,但其中某个字符串字段(例如 "child_sku_options")的值并非原始 JSON 对象,而是被双重编码的 JSON 字符串——它被 HTML 实体转义(如 \/ 代替 /、" 替代 "),导致直接解析报错或输出乱码。

你的原始代码:

print(json.loads(response.content))

看似合理,但问题出在 response.content 解析后得到的 data["results"][i]["child_sku_options"] 是一个字符串形式的、被 HTML 转义的 JSON,例如:

"{\"option_value_id\":197674,\"value\":\"12 Degree\",...\"image_url\":\"https:\\/\\/cdn11.bigcommerce.com\\/...jpg\"}"

该字符串中的 \/ 和 \" 是 HTML/XML 编码结果,并非标准 JSON 允许的原始反斜杠,因此无法被 json.loads() 直接识别。

✅ 正确处理流程如下:

  1. 先解析顶层 JSON:使用 response.json() 或 json.loads(response.content) 获取主数据结构;
  2. 定位被编码的字段:如 r["child_sku_options"](类型为 str);
  3. HTML 解码:调用 html.unescape() 消除 "、/、\/ 等转义,还原为标准 JSON 字符串;
  4. 二次 JSON 解析:对解码后的字符串执行 json.loads(),得到真正的 Python 字典/列表。

以下是完整、健壮的示例代码(含错误处理和推荐实践):

import json
import requests
from html import unescape

url = "https://547os1.a.searchspring.io/api/search/search.json?ajaxCatalog=v3&resultsFormat=native&siteId=547os1&domain=https%3A%2F%2Fwww.golfbox.com.au%2Fsearch%3Fq%3DCalaway%2BParadym%2BDriver%26Search%3DSEARCH&q=Calaway%20Paradym%20Driver"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
}

try:
    response = requests.get(url, headers=headers, timeout=10, verify=False)
    response.raise_for_status()  # 检查 HTTP 错误状态码

    # 解析顶层 JSON
    data = response.json()

    # 遍历搜索结果,提取并解析 child_sku_options
    for i, result in enumerate(data.get("results", [])):
        options_str = result.get("child_sku_options")
        if not isinstance(options_str, str) or not options_str.strip():
            print(f"[跳过] 第 {i+1} 条结果无 child_sku_options 字段")
            continue

        try:
            # 步骤1:HTML 解码 → 还原为标准 JSON 字符串
            decoded_str = unescape(options_str)
            # 步骤2:JSON 解析 → 转为 Python 对象
            options_list = json.loads(decoded_str)
            print(f"✅ 第 {i+1} 条结果解析成功,共 {len(options_list)} 个 SKU 选项:")
            # 示例:打印首个选项的 child_sku 和 price
            if options_list:
                first = options_list[0]
                print(f"   - SKU: {first.get('child_sku', 'N/A')}, Price: ${first.get('price', 'N/A')}")
        except json.JSONDecodeError as e:
            print(f"❌ 解析第 {i+1} 条的 child_sku_options 失败:{e}")
            print(f"   原始字符串(截取前100字符):{options_str[:100]}...")
        except Exception as e:
            print(f"⚠️  其他异常:{e

}") except requests.exceptions.RequestException as e: print(f"网络请求失败:{e}") except json.JSONDecodeError as e: print(f"顶层 JSON 解析失败:{e}")

? 关键注意事项:

  • ❌ 不要禁用 SSL 验证(verify=False)用于生产环境——它会带来安全风险。如遇证书问题,请更新 CA 证书或使用 requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS 调整 TLS 设置,而非关闭验证。
  • ✅ 优先使用 response.json() 而非 json.loads(response.content),前者自动处理编码(如 UTF-8 BOM、Content-Type charset),更可靠。
  • ✅ 始终校验字段是否存在(dict.get())、类型是否正确(isinstance(..., str)),避免 KeyError 或 TypeError。
  • ? 若发现 unescape() 后仍解析失败,可用 print(repr(decoded_str)) 查看真实字符串内容,确认是否含不可见控制字符(如 \u2028 行分隔符),必要时用正则清洗。

通过这一“HTML 解码 + 二次 JSON 解析”的组合策略,你就能稳定提取 SearchSpring 等平台返回的嵌套结构化商品选项数据,彻底告别 \/ 和 " 带来的解析困扰。


# ai  # 搜索结果  # 就能  # 是一个  # 这一  # 它会  # python  # safari  # windows  # 而非  # app  # 数据结构  # win  # js  # json  # go  # 对象  # html  # 编码  # xml  # 字符串  # 报错  # bom  # ssl  # 遍历  # print  # ajax  # 原为 


相关栏目: <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 AI推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 SEO优化<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 技术百科<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 谷歌推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 百度推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 网络营销<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 案例网站<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 精选文章<?muma echo $count; ?>

相关推荐

在线咨询

点击这里给我发消息QQ客服

在线咨询

免费通话

24h咨询:4006964355


如您有问题,可以咨询我们的24H咨询电话!

免费通话

微信扫一扫

微信联系
返回顶部