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

Python requests从GitLab下载YAML文件报JSONDecodeError解决方法

问题说明

使用Python requests库请求GitLab raw接口下载YAML文件时,请求可正常抵达目标资源,但执行print(g.json())时抛出JSON解码异常,异常触发后仍可看到预期的YAML文件内容。

原有错误实现代码:

GITLAB_FILE ="https://my_url/api/v4/projects/my_id/repository/files/path_and_filename.yaml/raw?ref=master&private_token=mytoken"
g=requests.request("GET", GITLAB_FILE, verify=False)
print(g.json())

抛出的核心报错:

json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
requests.exceptions.JSONDecodeError: [Errno Expecting value]
报错根因

你的判断完全准确:

  • 带/raw后缀的GitLab文件接口会直接返回文件的原始纯文本内容,响应格式不是JSON
  • requests的Response.json()方法会强制把响应文本按JSON格式反序列化,YAML内容不符合JSON语法规范,自然触发解析错误
  • 报错后仍能看到YAML内容,是因为响应对象已经完成了内容下载存储,仅JSON解析步骤执行失败。
正确实现方案

直接通过响应对象的.text属性获取原始YAML文本即可,无需调用.json()方法。

基础版本:直接获取YAML原始文本

import requests

# 可选:关闭verify=False触发的SSL证书校验警告
requests.packages.urllib3.disable_warnings()

GITLAB_FILE ="https://my_url/api/v4/projects/my_id/repository/files/path_and_filename.yaml/raw?ref=master&private_token=mytoken"
resp = requests.get(GITLAB_FILE, verify=False)
# 可选:增加状态码校验,遇到401权限不足、404文件不存在等问题直接抛错
resp.raise_for_status()

yaml_raw_content = resp.text
# 打印原始YAML内容,无解析报错
print(yaml_raw_content)

进阶版本:将YAML解析为Python结构化对象

如果需要把YAML内容转为字典、列表等Python可直接操作的对象,先安装PyYAML依赖:

pip install pyyaml

再增加解析逻辑:

import yaml

# 安全解析YAML,避免执行YAML中携带的不安全构造逻辑
yaml_struct_data = yaml.safe_load(yaml_raw_content)
# 打印解析后的结构化数据
print(yaml_struct_data)
优化建议
  • 不要把private_token直接拼接在URL参数中,建议放到请求头传递,避免token在日志、历史记录中泄露:
    headers = {"PRIVATE-TOKEN": "your_private_token"}
    resp = requests.get(GITLAB_FILE, headers=headers, verify=False)
    
  • 非内网测试场景不要开启verify=False,该配置会跳过SSL证书校验,存在中间人攻击风险。
  • 若调用不带/raw后缀的GitLab文件查询接口,接口会返回JSON格式响应,其中文件内容存放在content字段,为base64编码格式,需要单独解码才能拿到原始文本,使用raw接口配合.text获取内容的方式更直接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:51:20