Fork me on GitHub

Python重试的多重方法

1
这是崔斯特的第八十二篇原创文章

没人能保证自己的的程序没BUG,所以重试非常有必要。

下面说下我知道的几种Python重试方法。

装饰器

这是最最简单的重试方法,而且有现成的轮子,推荐两个:

  1. retrying
  2. tenacity

两种用法比较类似,我经常用后者,看下

1
2
3
4
5
6
7
8
9
10
11
import random
from tenacity import retry
@retry
def do_something_unreliable():
if random.randint(0, 10) > 1:
raise IOError("Broken sauce, everything is hosed!!!111one")
else:
return "Awesome sauce!"
print(do_something_unreliable())

用法非常简单,直接加上装饰器。当然也可以有各种自定义。

1
2
3
4
5
6
from tenacity import *
@retry(stop=(stop_after_delay(10) | stop_after_attempt(5)), wait=wait_fixed(2))
def stop_after_10_s_or_5_retries():
print("Stopping after 10 seconds or 5 retries")
raise Exception

以上是重试5次,每次间隔10秒,重试前等待2秒。

捕获异常

这种方法更常见

1
2
3
4
5
6
7
8
9
10
def func():
pass
for _ in range(0,100):
while True:
try:
func()
except SomeSpecificException:
continue
break

这里一定不要写成except或者except Exception,一定要指定异常,让别的错误打印出来,然后看日志再修改爬虫,或者会出现意想不到的情况。

举一个例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def verify_url(url):
import requests
try:
requests.get(url, timeout=10)
return True
except requests.exceptions.ConnectTimeout:
return False
def main():
for _ in range(5):
try:
if verify_url(''):
return
else:
continue
except KeyError:
continue
if __name__ == '__main__':
main()