使用seaborn的load_dataset()函数触发URLError问题求助
Python 3.8.10中seaborn.load_dataset('iris')超时报错的解决办法
问题详情
运行以下代码:
import seaborn as sns df = sns.load_dataset('iris')
出现TimeoutError及后续URLError,完整错误栈如下:
--------------------------------------------------------------------------- TimeoutError Traceback (most recent call last) File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\urllib\request.py:1354, in AbstractHTTPHandler.do_open(self, http_class, req, **http_conn_args) 1353 try: -> 1354 h.request(req.get_method(), req.selector, req.data, headers, 1355 encode_chunked=req.has_header('Transfer-encoding')) 1356 except OSError as err: # timeout error File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\http\client.py:1252, in HTTPConnection.request(self, method, url, body, headers, encode_chunked) 1251 """Send a complete request to the server.""" -> 1252 self._send_request(method, url, body, headers, encode_chunked) File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\http\client.py:1298, in HTTPConnection._send_request(self, method, url, body, headers, encode_chunked) 1297 body = _encode(body, 'body') -> 1298 self.endheaders(body, encode_chunked=encode_chunked) File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\http\client.py:1247, in HTTPConnection.endheaders(self, message_body, encode_chunked) 1246 raise CannotSendHeader() -> 1247 self._send_output(message_body, encode_chunked=encode_chunked) File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\http\client.py:1007, in HTTPConnection._send_output(self, message_body, encode_chunked) 1006 del self._buffer[:] -> 1007 self.send(msg) 1009 if message_body is not None: 1010 1011 # create a consistent interface to message_body File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\http\client.py:947, in HTTPConnection.send(self, data) 946 if self.auto_open: -> 947 self.connect() 948 else: File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\http\client.py:1414, in HTTPSConnection.connect(self) 1412 "Connect to a host on a given (SSL) port." -> 1414 super().connect() 1416 if self._tunnel_host: File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\http\client.py:918, in HTTPConnection.connect(self) 917 """Connect to the host and port specified in __init__.""" -> 918 self.sock = self._create_connection( 919 (self.host,self.port), self.timeout, self.source_address) 920 self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\socket.py:808, in create_connection(address, timeout, source_address) 807 try: -> 808 raise err 809 finally: 810 # Break explicitly a reference cycle File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\socket.py:796, in create_connection(address, timeout, source_address) 795 sock.bind(source_address) -> 796 sock.connect(sa) 797 # Break explicitly a reference cycle TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond During handling of the above exception, another exception occurred: URLError Traceback (most recent call last) Cell In[14], line 1 ----> 1 df = sns.load_dataset('iris') File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\site-packages\seaborn\utils.py:588, in load_dataset(name, cache, data_home, **kws) 586 if name not in get_dataset_names(): 587 raise ValueError(f"'{name}' is not one of the example datasets.") -> 588 urlretrieve(url, cache_path) 589 full_path = cache_path 590 else: File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\urllib\request.py:247, in urlretrieve(url, filename, reporthook, data) 230 """ 231 Retrieve a URL into a temporary location on disk. 232 (...) 243 data file as well as the resulting HTTPMessage object. 244 """ 245 url_type, path = _splittype(url) -> 247 with contextlib.closing(urlopen(url, data)) as fp: 248 headers = fp.info() 250 # Just return the local path and the "headers" for file:// 251 # URLs. No sense in performing a copy unless requested. File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\urllib\request.py:222, in urlopen(url, data, timeout, cafile, capath, cadefault, context) 220 else: 221 opener = _opener -> 222 return opener.open(url, data, timeout) File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\urllib\request.py:525, in OpenerDirector.open(self, fullurl, data, timeout) 522 req = meth(req) 524 sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method()) -> 525 response = self._open(req, data) 527 # post-process response 528 meth_name = protocol+"_response" File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\urllib\request.py:542, in OpenerDirector._open(self, req, data) 539 return result 541 protocol = req.type -> 542 result = self._call_chain(self.handle_open, protocol, protocol + 543 '_open', req) 544 if result: 545 return result File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\urllib\request.py:502, in OpenerDirector._call_chain(self, chain, kind, meth_name, *args) 500 for handler in handlers: 501 func = getattr(handler, meth_name) -> 502 result = func(*args) 503 if result is not None: 504 return result File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\urllib\request.py:1397, in HTTPSHandler.https_open(self, req) 1396 def https_open(self, req): -> 1397 return self.do_open(http.client.HTTPSConnection, req, 1398 context=self._context, check_hostname=self._check_hostname) File c:\Users\Argish\AppData\Local\Programs\Python\Python38\lib\urllib\request.py:1357, in AbstractHTTPHandler.do_open(self, http_class, req, **http_conn_args) 1354 h.request(req.get_method(), req.selector, req.data, headers, 1355 encode_chunked=req.has_header('Transfer-encoding')) 1356 except OSError as err: # timeout error -> 1357 raise URLError(err) 1358 r = h.getresponse() 1359 except: URLError:
已尝试卸载重装seaborn、排查防火墙设置(未阻止Python联网),均无效;切换到Python 3.10.6后代码可正常运行。
解决方法
1. 手动填充本地数据集缓存
seaborn会优先读取本地缓存的数据集,无需联网:
- 手动创建缓存目录:
C:\Users\Argish\AppData\Local\seaborn\seaborn-data - 从Python 3.10环境的对应缓存目录中复制
iris.csv到上述路径(3.10的缓存路径一般是C:\Users\Argish\AppData\Local\seaborn\seaborn-data) - 重新运行代码,将自动读取本地文件
2. 修复Python 3.8的SSL/网络组件
Python 3.8.10的urllib或SSL库可能存在兼容性问题,导致无法连接数据源服务器:
- 升级pip:
python -m pip install --upgrade pip
- 更新证书库:
python -m pip install --upgrade certifi
- 临时关闭SSL证书验证(仅用于测试,不推荐生产环境):
import ssl import seaborn as sns ssl._create_default_https_context = ssl._create_unverified_context df = sns.load_dataset('iris')
3. 绕开seaborn加载函数,直接用pandas读取
如果上述方法都不生效,直接读取本地的iris.csv文件:
import pandas as pd df = pd.read_csv('C:/Users/Argish/AppData/Local/seaborn/seaborn-data/iris.csv')
内容的提问来源于stack exchange,提问作者Argish Abhangi
相关产品推荐
相关产品推荐

