python 远程主机强迫关闭了一个现有的连接 socket 超时设置 errno 10054

部署运行你感兴趣的模型镜像

python socket.error: [Errno 10054] 远程主机强迫关闭了一个现有的连接。问题解决方案:

前几天使用python读取网页。因为对一个网站大量的使用urlopen操作,所以会被那个网站认定为攻击行为。有时就不再允许下载。导致urlopen()后,request.read()一直卡死在那里。最后会抛出errno 10054.

这个错误是connection reset by peer.也就是传说的远端主机重置了此连接。原因可能是socket超时时间过长;也可能是request = urllib.request.urlopen(url)之后,没有进行request.close()操作;也可能是没有sleep几秒,导致网站认定这种行为是攻击。

具体解决方案如下面的代码:

因为urlopen之后的read()操作其实是调用了socket层的某些函数。所以设置socket缺省超时时间,就可以让网络自己断掉。不必在read()处一直等待。

当然你也可以再外层再写几个try,except,例如:

一般来说就莫有问题了。我测试了几千个网页的下载,然后才说出此话。不过如果是下载成千上万的,我做了下测试,ms还是会跳出这个异常。可能是time.sleep()的时间太短,也可能是网络突然中断。我使用urllib.request.retrieve()测试了一下,发现不停的下载数据,总会有失败的情况出现。

简单的处理方法是:首先参照的我的文章:python检查点简单实现 。先做一个检查点。然后将以上会跑出异常的那段代码while True一下。参见下面的伪代码:

 

不过对于找不到相应的网页,又要做另外的一番处理:

如果大家还是遇到了问题...请再评论里注上其他解决方案。

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

<think>我们被要求使用中文回答,并且需要遵循严格的格式要求。用户的问题是关于在Python中设置脚本执行的超时时间。 根据引用[1]、[2]、[4]和[5],我们可以知道有几种方法可以设置超时时间: 1. 使用subprocess模块,并在其中设置超时(引用[1]和[4])。 2. 使用socket设置超时(引用[2]和[5]),但这里用户的问题是关于脚本执行的超时,所以更可能是执行外部命令或函数。 用户的问题没有明确是执行外部命令还是内部函数,但根据引用,我们主要看到两种场景: - 执行外部命令或脚本(使用subprocess) - 执行网络请求(如SSE连接,引用[3])或系统时间设置(引用[2]和[5]) 由于问题比较宽泛,我将分别讨论两种常见情况:执行外部命令和内部代码块的超时。 ### 情况1:执行外部命令或脚本 使用`subprocess`模块,我们可以设置超时时间,并在超时后终止进程。 引用[1]和[4]提供了使用subprocess的例子,其中引用[4]提到“python通过subprocess模块调用系统命令。实际使用中,有一次是命令进入了交互模式,结果web端直接卡死了。调用时设置一个超时时间,时间用完后自动断开。” 在Python 3.3及以上版本,`subprocess.run`有一个`timeout`参数,可以设置超时时间。如果超时,会抛出`subprocess.TimeoutExpired`异常。 示例代码: ```python import subprocess try: # 设置超时时间为10秒 result = subprocess.run(['your_command', 'arg1', 'arg2'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=10) print(result.stdout.decode()) except subprocess.TimeoutExpired: print("命令执行超时!") ``` 对于更复杂的控制(如引用[1]中的例子),我们可以使用`subprocess.Popen`并配合轮询和超时机制。 ### 情况2:执行内部代码块(函数)的超时 如果我们需要对一段Python代码(函数)设置超时,可以使用信号(signal)或多线程/多进程。但注意,信号方法在Windows上可能不可用,而且主线程中使用信号可能会影响整个程序。 另一种方法是使用多进程,因为终止一个子进程比终止一个线程更安全。 使用`multiprocessing`模块的例子: ```python import multiprocessing import time def your_function(): # 模拟长时间运行的任务 time.sleep(20) return "完成" if __name__ == '__main__': pool = multiprocessing.Pool(processes=1) result = pool.apply_async(your_function) try: # 设置超时时间为10秒 output = result.get(timeout=10) print(output) except multiprocessing.TimeoutError: print("函数执行超时!") pool.terminate() # 终止进程池 pool.join() ``` 另外,也可以使用第三方库如`func_timeout`,它提供了更简单的超时控制。 ### 其他情况:网络请求等 对于网络请求,通常使用的库(如requests)有内置的超时参数。例如: ```python import requests try: response = requests.get('http://example.com', timeout=5) # 5秒超时 print(response.text) except requests.exceptions.Timeout: print("请求超时") ``` 对于SSE连接(引用[3]),我们可以通过设置底层的socket超时或使用带有超时控制的SSE客户端。 ### 总结 根据不同的场景,设置超时的方法不同: 1. 执行外部命令:使用`subprocess`模块的`timeout`参数。 2. 执行内部函数:使用多进程和`get`方法的`timeout`参数,或者使用第三方库。 3. 网络请求:使用相应库的超时参数。 现在,根据要求,我们需要生成相关问题。 §§相关问题§§ 1. 如何在Windows上设置Python函数的执行超时? 2. 使用subprocess设置超时后,如何获取超时前已经输出的内容? 3. 除了subprocess和multiprocessing,还有哪些方法可以设置超时? 4. 如何处理超时后资源的清理工作?</think>### Python设置脚本执行超时时间的方法 在Python中设置脚本执行的超时时间,主要有以下几种方法: #### 1. 使用subprocess模块(推荐) ```python import subprocess try: # 设置10秒超时 result = subprocess.run( ['python', 'your_script.py'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=10 # 超时时间() ) print("输出:", result.stdout.decode()) except subprocess.TimeoutExpired: print("执行超时! 已终止进程") ``` #### 2. 使用signal模块(仅限Unix系统) ```python import signal import sys def handler(signum, frame): print("执行超时!") sys.exit(1) # 设置5秒超时 signal.signal(signal.SIGALRM, handler) signal.alarm(5) # 你的代码 try: # 需监控的代码块 time.sleep(10) # 模拟耗时操作 finally: signal.alarm(0) # 取消定时器 ``` #### 3. 使用多线程/进程(跨平台) ```python from multiprocessing import Pool import time def run_script(): # 需执行的函数 time.sleep(20) return "完成" if __name__ == '__main__': with Pool(processes=1) as pool: result = pool.apply_async(run_script) try: output = result.get(timeout=10) # 10秒超时 print(output) except TimeoutError: print("执行超时! 终止中...") pool.terminate() ``` #### 4. 使用装饰器(函数级超时) ```python import functools import errno import os import signal class TimeoutError(Exception): pass def timeout(seconds=10): def decorator(func): def wrapper(*args, **kwargs): def handler(signum, frame): raise TimeoutError("函数执行超时") signal.signal(signal.SIGALRM, handler) signal.alarm(seconds) try: result = func(*args, **kwargs) finally: signal.alarm(0) return result return wrapper return decorator @timeout(5) def long_running_task(): time.sleep(10) return "完成" ``` ### 关键注意事项 1. **外部命令**:执行外部脚本建议使用`subprocess`,它能自动处理子进程终止[^4] 2. **资源清理**:超时后务必终止相关进程/线程,避免资源泄漏 3. **Windows限制**:`signal`模块在Windows上功能有限,建议使用`multiprocessing` 4. **精度问题**:超时控制精度通常在毫秒级,不能保证精确到微秒 5. **异常处理**:超时后应妥善处理中断状态和清理资源 > 对于网络请求超时,建议直接使用库的内置参数(如`requests.get(timeout=5)`),而非进程级控制[^3]。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值