python - 如何在 x 异常或 403 后计数和停止脚本
问题描述
我一直在尝试学习如何正确编写计数器和“停止器”,例如状态 403 x 连续 10 次,或者如果我连续 10 次遇到连接错误。
现在我做了这样的事情:
import requests
import time
from requests.exceptions import ConnectionError, ReadTimeout, RequestException, Timeout
exception_counter = 0
while True:
try:
response = requests.get("https://stackoverflow.com/", timeout=12)
if response.ok:
print("Very nice")
time.sleep(60)
else:
print(
f'[Response -> {response.status_code}]'
f'[Response Url -> {response.url}]'
)
time.sleep(60)
if response.status_code == 403:
if exception_counter >= 10:
print("Hit limitation of counter: Response [403]")
time.sleep(4294968)
exception_counter += 1
except (ConnectionError) as err:
print(err)
time.sleep(random.randint(1, 3))
if exception_counter >= 10:
print(f"Hit limitation of coonnectionerror {err}")
time.sleep(4294968)
continue
exception_counter += 1
continue
except (ReadTimeout, Timeout) as err:
print(err)
time.sleep(random.randint(1, 3))
continue
except RequestException as err:
print(err)
time.sleep(random.randint(1, 3))
continue
except Exception as err:
print(err)
time.sleep(random.randint(1, 3))
if exception_counter >= 10:
print(f"Hit limitation of Exception {err}")
time.sleep(4294968)
continue
exception_counter += 1
continue
但是,我并不担心我在不同地方重复相同代码的地方是否正确。我想知道如何以正确和正确的方式实际做到这一点,与我在不同地方重复相同代码所做的事情相比
编辑:
更新代码:
现在的问题是,每当我们成功打印时,我想重置计数器,但现在没有。
import time
import requests
class ExceptionCounter:
def __init__(self):
self.count = 0
def check(self, message):
self.count += 1
print(self.count)
if self.count > 3:
print(message, 'exceeded 3 counts')
time.sleep(6000)
exception_counter = ExceptionCounter()
def main():
while True:
response = requests.post("https://www.google.se/")
print(response.status_code)
if response.ok:
print("Yay! Now I want to reset my counter because it got successful!")
else:
exception_counter.check(f"Ahhhh, wrong status code! {response.status_code}!")
time.sleep(1)
main()
解决方案
requests
由 支持urllib3
,因此您可以只配置一些内置的重试功能,而不是滚动您自己的计数器。
下面的文章是一个很好的资源,并介绍了一些其他常见的高级用例requests
。
https://findwork.dev/blog/advanced-usage-python-requests-timeouts-retries-hooks/
这是一个修改后的使用示例。
import logging
import requests
from requests.adapters import HTTPAdapter
from requests.exceptions import RequestException
from requests.packages.urllib3.util.retry import Retry
DEFAULT_TIMEOUT = 12 # seconds
def main():
logging.basicConfig(level=logging.DEBUG)
retry_strategy = Retry(
total=10,
backoff_factor=1,
status_forcelist=[403, 429, 500, 502, 503, 504],
)
adapter = TimeoutHTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)
url = "https://notarealsite.foo/"
try:
response = http.get(url)
response.raise_for_status()
except RequestException:
logging.exception(f"Problem with request to {url}")
class TimeoutHTTPAdapter(HTTPAdapter):
def __init__(self, *args, **kwargs):
self.timeout = DEFAULT_TIMEOUT
if "timeout" in kwargs:
self.timeout = kwargs["timeout"]
del kwargs["timeout"]
super().__init__(*args, **kwargs)
def send(self, request, **kwargs):
timeout = kwargs.get("timeout")
if timeout is None:
kwargs["timeout"] = self.timeout
return super().send(request, **kwargs)
if __name__ == "__main__":
main()
这会设置日志DEBUG
级别,以便您可以看到重试发生了什么。
我使用了您的超时 12 并添加了 403,但您应该注意 403 不是重试的有效状态。请参阅以下内容以了解原因。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403
HTTP
403 Forbidden
客户端错误状态响应码表示服务器理解请求但拒绝授权。此状态类似于
401
,但在这种情况下,重新认证将没有任何区别。访问被永久禁止并与应用程序逻辑相关联,例如对资源的权限不足。
推荐阅读
- django - 自定义限制问题
- c# - 在字符串 C# 中的特定字符之间查找和移动未知单词
- node.js - 如何将段落对齐添加到 Pug 模板?
- c# - 是否有在所有 Control_Prerender 事件之后触发的事件
- c++ - Boost 库需要我认为没有必要的 lib 文件
- .net - 运行测试时 .net sdk 和 .net core 之间不兼容
- arrays - 使用 Excel 循环 (VBA) 更新数组范围
- javascript - D3js v5 是否向后兼容 v4?
- php - 表格行无法正确使用 codeigniter 中的分页
- donejs - DoneJS - 动态加载器