如何单独计算每个异常

How to count each exception by itself

我目前一直在创建自己的异常等工作:

# -*- coding: utf-8 -*-

# ------------------------------------------------------------------------------- #

"""
exceptions
~~~~~~~~~~~~~~~~~~~
This module contains the set of multiple exceptions.
"""


# ------------------------------------------------------------------------------- #


class RequestsException(Exception):
    """
    Base exception class
    """


class TooManyFailedRequests(RequestsException):
    """
    Raise an exception for FailedRequests
    """


class TooManyTimedOut(RequestsException):
    """
    Raise an exception for TimedOut
    """

并且我创建了一个带有计数器的脚本:

import time

import requests
from requests.exceptions import ConnectionError, ReadTimeout, Timeout

from lib.exceptions import (
    TooManyFailedRequests,
    TooManyTimedOut
)


def send_notification(msg):
    print(f"Sending notification to discord later on! {msg}")


class simpleExceptionWay:
    """
    Counter to check if we get exceptions x times in a row.
    """

    def __init__(self):
        self.failedCnt = 0

    def check(self, exception, msg):
        self.failedCnt += 1
        if self.failedCnt > 2:
            send_notification(msg)
            raise exception(msg)

    def reset(self):
        self.failedCnt = 0


# Call this function where we want to check
# simpleException.check(exception, msg)
simpleException = simpleExceptionWay()


def test():
    """
    We also want to count in here if we ever reach in here.
    """

    return "Hello world"


def setup_scraper(site_url):
    session = requests.session()

    while True:

        try:
            response = session.post(site_url, timeout=5)

            if response.ok:
                simpleException.reset()
                exit()

            if response.status_code in {429, 403, 405}:
                print(f"Status -> {response.status_code}")

                simpleException.check(
                    TooManyFailedRequests,
                    {
                        'Title': f'Too many {response.status_code} requests in a row',
                        'Reason': str(),
                        'URL': str(site_url),
                        'Proxies': str(
                            session.proxies
                            if session.proxies
                            else "No proxies used"
                        ),
                        'Headers': str(session.headers),
                        'Cookies': str(session.cookies)
                    }
                )

                time.sleep(3)
                continue

        except (ReadTimeout, Timeout, ConnectionError) as err:

            simpleException.check(
                TooManyTimedOut,
                {
                    'Title': f'Timed out',
                    'Reason': "Too many timed out",
                    'URL': str(site_url),
                    'Proxies': str(
                        session.proxies
                        if session.proxies
                        else "No proxies used"
                    ),
                    'Headers': str(session.headers),
                    'Cookies': str(session.cookies)
                }
            )
            continue


if __name__ == "__main__":
    setup_scraper("https://www.google.se/")

我目前的问题是我只有 1 个计数器一起计数,我想知道我该怎么做,例如,如果我们连续达到 TooManyTimedOut 100 次,然后我们想加注,什么时候加注连续 5 次达到 TooManyFailedRequests 那么我们应该引发异常。可以吗?

您可以使用 type() 函数获取异常的类型,然后使用该类型的 name 属性 将其名称作为字符串获取.然后您可以将其存储在一个字典中,该字典将跟踪异常计数。

class simpleExceptionWay:
    """
    Counter to check if we get exceptions x times in a row.
    """

    def __init__(self):
        self.exception_count = {}

    def check(self, exception, msg):
        exception_name = exception.__name__

        # the dict.get() method will return the value from a dict if exists, else it will return the value provided
        self.exception_count[exception_name] = self.exception_count.get(exception_name, 0) + 1
          
        if self.exception_count[exception_name] > 2:
            send_notification(msg)
            raise exception(msg)

    def reset(self):
        self.exception_count.clear()