小能豆

如果需要太长时间才能完成,则超时功能

javascript

我有一个 shell 脚本,它循环遍历包含我想要访问并截取屏幕截图的 URL 的文本文件。

这一切都完成了,而且很简单。脚本初始化一个类,该类在运行时会创建列表中每个站点的屏幕截图。有些站点需要很长时间才能加载,有些站点可能根本无法加载。所以我想将屏幕抓取函数包装在一个超时脚本中,False如果函数无法在 10 秒内完成,则让它返回。

我对最简单的解决方案感到满意,也许设置一个异步计时器,无论函数内部实际发生什么,它都会在 10 秒后返回 False?


阅读 56

收藏
2024-07-05

共1个答案

小能豆

要在 Python 中实现一个简单的超时机制,你可以使用 subprocess 模块启动一个带有超时的子进程,并在特定时间后终止它。这种方法适用于你的情况,其中你想要执行某些操作,例如访问网站并捕获屏幕截图,但希望在超时发生时能够立即返回 False

使用 subprocesstimeout 的方法

  1. 导入模块

python import subprocess import threading

  1. 定义超时异常

python class TimeoutException(Exception): pass

  1. 定义执行函数

python def execute_with_timeout(command, timeout): """ Execute a command with a timeout """ proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) timer = threading.Timer(timeout, proc.kill) try: timer.start() stdout, stderr = proc.communicate() return stdout.decode('utf-8'), stderr.decode('utf-8'), proc.returncode finally: timer.cancel()

  1. 示例用法

假设你有一个函数 take_screenshot(url),它负责访问给定 URL 并截取屏幕截图。你可以使用上面定义的 execute_with_timeout 函数来调用它,并设置超时时间。

```python
def take_screenshot(url):
# 实现截图逻辑,返回 True 或 False
pass

url = "http://example.com
command = [“python3”, “screenshot_script.py”, url] # 替换成实际的截图脚本和参数
timeout_seconds = 10

try:
stdout, stderr, returncode = execute_with_timeout(command, timeout_seconds)
if returncode == 0:
print(“Screenshot taken successfully”)
else:
print(“Screenshot failed”)
except TimeoutException:
print(“Screenshot timed out after {} seconds”.format(timeout_seconds))
```

解释

  • execute_with_timeout 函数:
  • 接受一个命令列表 command 和超时时间 timeout
  • 使用 subprocess.Popen 启动一个子进程来执行命令。
  • 使用 threading.Timer 创建一个计时器,当超时时调用 proc.kill() 终止子进程。
  • 使用 proc.communicate() 等待子进程完成,并获取其标准输出、标准错误和返回码。
  • 返回获取到的标准输出、标准错误、和返回码。

  • take_screenshot 函数:

  • 这是你实现的截图逻辑,可以根据实际情况编写。

  • 示例用法:

  • 定义一个要执行的命令列表 command,其中包含执行截图脚本的命令和参数。
  • 设置超时时间 timeout_seconds
  • 使用 execute_with_timeout 函数执行命令,并根据返回码判断执行结果。

这种方法允许你在超时发生时终止正在执行的任务(如访问网站和截图),并及时返回 False,而不会阻塞程序。

2024-07-05