request.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import time
  2. import requests
  3. from requests.exceptions import RequestException
  4. from ak.exceptions import NetworkError, APIError, RateLimitError, DataParsingError
  5. from ak.utils.context import config
  6. def make_request_with_retry_json(
  7. url, params=None, headers=None, proxies=None, max_retries=3, retry_delay=1
  8. ):
  9. """
  10. 发送 HTTP GET 请求,支持重试机制和代理设置。
  11. :param url: 请求的 URL
  12. :param params: URL 参数 (可选)
  13. :param headers: 请求头 (可选)
  14. :param proxies: 代理设置 (可选)
  15. :param max_retries: 最大重试次数
  16. :param retry_delay: 初始重试延迟(秒)
  17. :return: 解析后的 JSON 数据
  18. """
  19. if proxies is None:
  20. proxies = config.proxies
  21. for attempt in range(max_retries):
  22. try:
  23. response = requests.get(
  24. url, params=params, headers=headers, proxies=proxies
  25. )
  26. if response.status_code == 200:
  27. try:
  28. data = response.json()
  29. if not data:
  30. raise DataParsingError("Empty response data")
  31. return data
  32. except ValueError:
  33. raise DataParsingError("Failed to parse JSON response")
  34. elif response.status_code == 429:
  35. raise RateLimitError(
  36. f"Rate limit exceeded. Status code: {response.status_code}"
  37. )
  38. else:
  39. raise APIError(
  40. f"API request failed. Status code: {response.status_code}"
  41. )
  42. except (RequestException, RateLimitError, APIError, DataParsingError) as e:
  43. if attempt == max_retries - 1:
  44. if isinstance(e, RateLimitError):
  45. raise
  46. elif isinstance(e, (APIError, DataParsingError)):
  47. raise
  48. else:
  49. raise NetworkError(
  50. f"Failed to connect after {max_retries} attempts: {str(e)}"
  51. )
  52. time.sleep(retry_delay)
  53. retry_delay *= 2 # 指数退避策略
  54. raise NetworkError(f"Failed to connect after {max_retries} attempts")
  55. def make_request_with_retry_text(
  56. url, params=None, headers=None, proxies=None, max_retries=3, retry_delay=1
  57. ):
  58. """
  59. 发送 HTTP GET 请求,支持重试机制和代理设置。
  60. :param url: 请求的 URL
  61. :param params: URL 参数 (可选)
  62. :param headers: 请求头 (可选)
  63. :param proxies: 代理设置 (可选)
  64. :param max_retries: 最大重试次数
  65. :param retry_delay: 初始重试延迟(秒)
  66. :return: 解析后的 JSON 数据
  67. """
  68. if proxies is None:
  69. proxies = config.proxies
  70. for attempt in range(max_retries):
  71. try:
  72. response = requests.get(
  73. url, params=params, headers=headers, proxies=proxies
  74. )
  75. if response.status_code == 200:
  76. try:
  77. data = response.text
  78. if not data:
  79. raise DataParsingError("Empty response data")
  80. return data
  81. except ValueError:
  82. raise DataParsingError("Failed to parse JSON response")
  83. elif response.status_code == 429:
  84. raise RateLimitError(
  85. f"Rate limit exceeded. Status code: {response.status_code}"
  86. )
  87. else:
  88. raise APIError(
  89. f"API request failed. Status code: {response.status_code}"
  90. )
  91. except (RequestException, RateLimitError, APIError, DataParsingError) as e:
  92. if attempt == max_retries - 1:
  93. if isinstance(e, RateLimitError):
  94. raise
  95. elif isinstance(e, (APIError, DataParsingError)):
  96. raise
  97. else:
  98. raise NetworkError(
  99. f"Failed to connect after {max_retries} attempts: {str(e)}"
  100. )
  101. time.sleep(retry_delay)
  102. retry_delay *= 2 # 指数退避策略
  103. raise NetworkError(f"Failed to connect after {max_retries} attempts")