| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- import time
- import requests
- from requests.exceptions import RequestException
- from ak.exceptions import NetworkError, APIError, RateLimitError, DataParsingError
- from ak.utils.context import config
- def make_request_with_retry_json(
- url, params=None, headers=None, proxies=None, max_retries=3, retry_delay=1
- ):
- """
- 发送 HTTP GET 请求,支持重试机制和代理设置。
- :param url: 请求的 URL
- :param params: URL 参数 (可选)
- :param headers: 请求头 (可选)
- :param proxies: 代理设置 (可选)
- :param max_retries: 最大重试次数
- :param retry_delay: 初始重试延迟(秒)
- :return: 解析后的 JSON 数据
- """
- if proxies is None:
- proxies = config.proxies
- for attempt in range(max_retries):
- try:
- response = requests.get(
- url, params=params, headers=headers, proxies=proxies
- )
- if response.status_code == 200:
- try:
- data = response.json()
- if not data:
- raise DataParsingError("Empty response data")
- return data
- except ValueError:
- raise DataParsingError("Failed to parse JSON response")
- elif response.status_code == 429:
- raise RateLimitError(
- f"Rate limit exceeded. Status code: {response.status_code}"
- )
- else:
- raise APIError(
- f"API request failed. Status code: {response.status_code}"
- )
- except (RequestException, RateLimitError, APIError, DataParsingError) as e:
- if attempt == max_retries - 1:
- if isinstance(e, RateLimitError):
- raise
- elif isinstance(e, (APIError, DataParsingError)):
- raise
- else:
- raise NetworkError(
- f"Failed to connect after {max_retries} attempts: {str(e)}"
- )
- time.sleep(retry_delay)
- retry_delay *= 2 # 指数退避策略
- raise NetworkError(f"Failed to connect after {max_retries} attempts")
- def make_request_with_retry_text(
- url, params=None, headers=None, proxies=None, max_retries=3, retry_delay=1
- ):
- """
- 发送 HTTP GET 请求,支持重试机制和代理设置。
- :param url: 请求的 URL
- :param params: URL 参数 (可选)
- :param headers: 请求头 (可选)
- :param proxies: 代理设置 (可选)
- :param max_retries: 最大重试次数
- :param retry_delay: 初始重试延迟(秒)
- :return: 解析后的 JSON 数据
- """
- if proxies is None:
- proxies = config.proxies
- for attempt in range(max_retries):
- try:
- response = requests.get(
- url, params=params, headers=headers, proxies=proxies
- )
- if response.status_code == 200:
- try:
- data = response.text
- if not data:
- raise DataParsingError("Empty response data")
- return data
- except ValueError:
- raise DataParsingError("Failed to parse JSON response")
- elif response.status_code == 429:
- raise RateLimitError(
- f"Rate limit exceeded. Status code: {response.status_code}"
- )
- else:
- raise APIError(
- f"API request failed. Status code: {response.status_code}"
- )
- except (RequestException, RateLimitError, APIError, DataParsingError) as e:
- if attempt == max_retries - 1:
- if isinstance(e, RateLimitError):
- raise
- elif isinstance(e, (APIError, DataParsingError)):
- raise
- else:
- raise NetworkError(
- f"Failed to connect after {max_retries} attempts: {str(e)}"
- )
- time.sleep(retry_delay)
- retry_delay *= 2 # 指数退避策略
- raise NetworkError(f"Failed to connect after {max_retries} attempts")
|