项目是一款后端挂机采集的脚本。其中使用 requests.get 来请求数据,需要解析出json。但会遇到一些意外错误。

错误:

raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

上面的错误是由于接口没有返回正确的json格式,导致 json.loads时发生了错误。因此需要对数据进行判断过滤

业务代码:

url = 'http://xx.xx/api'
r = requests.get(url, verify=False)
res = json.loads(r.text) # 解析数据
tool.log('页面数据', r.text)

这样写似乎没有问题,但长期的挂机总会发生意想不到的问题。如接口网站可能500,400,502等,或请求requests时发生了意想不到的错误。会直接报错终止运行。对于一款长期挂机的脚本,这样的预期结果很明显是不能满足的。因此需要做一些判断改动。

改动后:

url = 'http://xx.xx/api'
# 默认状态码
status = 0
# 如果状态码不等于200 则继续重试请求,直到请求正确为止
while status != 200:
    try:
        r = requests.get(url, verify=False)
        # 请求成功 之后把状态码赋给status
        status = r.status_code
    except Exception as e:
        # 如果请求时requests发送了错误,打印报错。但不阻塞,继续尝试
        tool.log("请求接口时出错:%s" % (e))

res = json.loads(r.text)
# res拿到请求结果 继续业务逻辑

上面的代码,可以解决因为接口地址非200而终止运行的问题。但为了更严谨。防止接口失效而一直陷入循环。可以加上重试次数的判断和延迟。

最终改造后如下:

url = 'http://xx.xx/api'
getCount = 0
res = None
# 默认状态码
status = 0
# 如果状态码不等于200 则重试5次请求,直到请求正确为止
while status != 200 or getCount <= 5:
    try:
        r = requests.get(url, verify=False)
        # 请求成功 之后把状态码赋给status
        status = r.status_code
    except Exception as e:
        # 如果请求时requests发送了错误,打印报错。但不阻塞,继续尝试
        tool.log("请求接口时出错:%s" % (e))

    getCount += 1
    # 延时1秒 防止无限制请求
    time.sleep(1)

if res is None:
    # 重试了5次 仍然没有成功 终止继续
    return False

res = json.loads(r.text)
# res拿到请求结果 继续业务逻辑
最后修改于:2021-10-28 15:35
文章链接: https://oct.cn/view/111
版权声明: 本站所有文章除特别声明外。转载请注明来自 十月笔记