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

Python调用Wikidata SPARQL扩展时间范围触发JSONDecodeError求助

解决Wikidata大时间范围查询的JSON解析错误问题

看起来你在处理Wikidata大体积响应时遇到了标准JSON解析的兼容性问题——这种情况在数据量激增时很常见:Wikidata返回的响应里可能混入了非标准控制字符、语法不严谨的格式(比如单引号代替双引号),或是网络传输中出现了部分数据丢失。我给你几个可行的解决方案,按优先级尝试:

1. 先确保响应的完整性与编码正确性

首先排查是不是请求本身出了问题,比如网络丢包导致响应不完整。在解析前先做这些基础检查:

import requests
import json

url = "你的Wikidata查询URL"
response = requests.get(url)
# 先确保请求成功,避免HTTP错误导致的无效响应
response.raise_for_status()
# 用utf-8解码,替换无法识别的字符,避免编码问题引发解析错误
json_str = response.content.decode('utf-8', errors='replace')

2. 换用容错性更强的JSON解析库

标准库的json模块对格式要求非常严格,试试第三方库来处理非标准JSON:

  • simplejson:支持忽略部分格式错误
    先安装:pip install simplejson
    然后使用:
    import simplejson
    try:
        data = simplejson.loads(json_str, ignore_errors=True)
    except simplejson.JSONDecodeError as e:
        print(f"解析错误:{e}")
    
  • demjson:专门处理不严格的JSON格式
    安装:pip install demjson
    使用:
    import demjson
    data = demjson.decode(json_str)
    

3. 定位并修复响应中的错误字符

根据你得到的报错行号和列号,先把响应内容保存到本地,手动排查问题:

# 把响应内容写入本地文件,方便定位错误
with open('wikidata_response.json', 'w', encoding='utf-8') as f:
    f.write(json_str)

用文本编辑器(比如VS Code)打开文件,跳转到报错的行/列位置,针对性修复:

  • 如果是控制字符(非换行、制表符的不可打印字符),用正则替换:
    import re
    # 移除所有ASCII控制字符(保留换行、回车、制表符)
    json_str = re.sub(r'[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]', '', json_str)
    
  • 如果是单引号代替双引号的问题,用正则精准替换属性名的单引号:
    # 替换属性名的单引号为双引号(适配常见的非标准格式)
    json_str = re.sub(r"(\w+)\s*:\s*'", r'\1:"', json_str)
    json_str = re.sub(r"'\s*,\s*(\w+)\s*:", r'",\1:', json_str)
    json_str = re.sub(r"'\s*}$", r'"}', json_str)
    

4. 拆分查询,减少单次返回数据量

既然短时间范围查询正常,不如把1870-1874的时间范围拆分成多个小批次(比如按年拆分),分批请求后合并结果,这是最稳定的方案:

# 示例:按年拆分时间范围
time_ranges = [
    ("1870-01-02", "1871-01-01"),
    ("1871-01-01", "1872-01-01"),
    ("1872-01-01", "1873-01-01"),
    ("1873-01-01", "1874-01-04")
]

all_results = []
for start, end in time_ranges:
    # 构造对应时间范围的Wikidata查询URL
    query_url = f"你的查询URL&start={start}&end={end}"
    response = requests.get(query_url)
    response.raise_for_status()
    data = json.loads(response.text)
    all_results.extend(data.get('results', []))

# 处理合并后的结果
print(f"总共获取到{len(all_results)}条数据")

优先试试拆分查询(最稳定)或者换用第三方解析库(最省心),如果还是不行,再手动定位修复错误字符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 11:32:29