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

网页抓取时遭遇JSONDecodeError错误,寻求解决方案

解决Wayback Machine API调用时的JSONDecodeError问题

我完全懂你这种头疼的感觉——之前好好运行的代码突然报错,自己还没改任何东西,确实摸不着头脑。咱们一步步拆解问题、修复它:

问题重现

你原本想用这段代码通过Wayback Machine的元数据API获取站点最早存档年份:

import json
import requests
my_list=['www.expedia.it', 'www.fortuneita.com', 'www.finanzaonline.com', 'it-it.facebook.com', 'www.capterra.it', 'www.sportmediaset.mediaset.it', 'www.incredibile.net', 'www.newsrimini.it', 'web.tiscali.it', 'www.dettiescritti.com']
api_url = 'https://web.archive.org/__wb/search/metadata'
for url in my_list:
    data = requests.get(api_url, params={'q': url}).json()
    min_year = min(data['urls'], key=int)

结果触发了这个错误:

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

错误原因分析

这个错误的核心是API返回的不是有效的JSON数据,大概率是这几个原因导致的:

  • Wayback Machine有请求频率限制,你的循环请求太密集,触发了限流,服务器返回了HTML格式的错误页(比如429 Too Many Requests)
  • 部分域名没有存档数据,API返回了空或者非JSON格式的响应
  • 请求没有携带浏览器标识的请求头,被服务器识别为爬虫,返回了异常内容

修复方案

针对这些问题,我们给代码加几个关键改进:

1. 先校验响应状态,避免直接解析无效内容

在调用.json()之前,先判断响应是否成功(状态码200),失败时打印响应内容方便排查。

2. 添加浏览器请求头,规避爬虫检测

给请求加上模拟浏览器的User-Agent,让请求看起来更像正常用户访问。

3. 增加请求延迟,避免触发限流

在循环中加入短暂延迟,控制请求频率,降低被拦截的概率。

4. 处理空结果场景

如果站点没有存档数据,提前判断并跳过,避免min()函数报错。

完整修复后的代码

import json
import requests
import time

my_list=['www.expedia.it', 'www.fortuneita.com', 'www.finanzaonline.com', 'it-it.facebook.com', 'www.capterra.it', 'www.sportmediaset.mediaset.it', 'www.incredibile.net', 'www.newsrimini.it', 'web.tiscali.it', 'www.dettiescritti.com']
api_url = 'https://web.archive.org/__wb/search/metadata'

# 模拟浏览器请求头,避免被识别为爬虫
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}

for url in my_list:
    try:
        # 发送带请求头的请求
        response = requests.get(api_url, params={'q': url}, headers=headers)
        # 检查响应状态,非200则抛出异常
        response.raise_for_status()
        
        data = response.json()
        # 检查是否存在有效存档数据
        if 'urls' in data and data['urls']:
            min_year = min(data['urls'], key=int)
            print(f"{url} 的最早存档年份: {min_year}")
        else:
            print(f"{url} 未找到存档数据")
        
        # 每次请求后延迟1秒,避免触发限流
        time.sleep(1)
    except requests.exceptions.RequestException as e:
        print(f"请求 {url} 时出错: {str(e)}")
        # 打印部分响应内容,方便排查问题
        if response.content:
            print(f"响应内容预览: {response.text[:200]}...")
    except json.JSONDecodeError:
        print(f"{url} 返回的内容不是有效的JSON格式")
        print(f"响应内容预览: {response.text[:200]}...")

额外提示

  • Wayback Machine没有公开的限流规则,但保持1秒/次的请求频率基本不会被拦截,如果还是遇到问题,可以适当延长延迟时间
  • 部分站点可能确实没有被Wayback Machine存档,代码里已经做了空值处理,不会中断整个循环

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 11:12:48