Python requests访问无效URL触发socket.gaierror报错的解决方案
问题原因
代码存在两个核心问题:
requests.get()在域名解析失败、网络中断、连接超时这类根本拿不到服务端响应的场景下,会直接抛出异常,不会返回带状态码的响应对象,因此你写的状态码判断逻辑根本不会执行。你碰到的socket.gaierror: [Errno 8] nodename nor servname provided, or not known就是典型的域名解析失败报错——你填写的域名不存在,DNS查询不到对应服务器IP,请求在建立连接阶段就直接中断了。- 就算请求顺利拿到响应,
if res == 200的写法也是错误的:res是Response类型的对象,和整数200做相等判断永远不会得到True结果,状态码需要通过res.status_code属性获取。
修复方案
通过try/except捕获请求全流程的异常,同时修正状态码的判断逻辑,参考代码如下:
import requests url = "http://sdfsdfasdfsfsdf.com" try: # 建议加上timeout参数,避免网络异常时程序无限等待卡死 res = requests.get(url, timeout=10) if res.status_code == 200: print("ok") else: print(f"wrong,响应状态码:{res.status_code}") except Exception as e: # 域名解析失败、断网、连接超时、连接被拒绝等所有请求阶段的异常都会进入该分支 print(f"wrong,请求发生异常:{str(e)}")
额外优化说明
- 如果不想捕获所有类型的异常,可以将
except后的Exception替换为requests.exceptions.RequestException,这是requests库所有请求相关异常的基类,既能覆盖所有请求阶段的报错,也不会意外捕获到代码其他位置的逻辑异常。 - 如果希望4xx、5xx这类错误状态码也直接进入异常分支,可以在获取到响应对象后执行
res.raise_for_status(),该方法会在状态码为400及以上时主动抛出HTTP异常,无需单独写状态码非200的判断分支。
内容的提问来源于stack exchange,提问作者JeongJu Lee
相关产品推荐
相关产品推荐

