如何用Python的requests库实现POST请求5次重试(间隔10秒)
Got it, I totally get why this is frustrating—most retry examples floating around focus on GET requests, but POST needs a bit more intentional setup, especially since you want fixed 10-second delays and exactly 5 retries for 503 errors. Let’s walk through two reliable approaches using Python’s requests library:
Approach 1: Use requests.Session with urllib3.Retry (Clean, Built-in)
This method leverages requests's adapter system and urllib3's retry logic. The key here is explicitly allowing POST retries (they’re not enabled by default!) and targeting only 503 status codes.
import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry def create_retry_session(retries=5, delay=10): session = requests.Session() # Configure retry strategy: note that backoff_factor creates exponential delays here # (10s, 20s, 40s...). For strictly fixed delays, skip to Approach 2. retry_strategy = Retry( total=retries, status_forcelist=[503], # Only retry when we get a 503 allowed_methods=["POST"], # Critical: enable retries for POST requests backoff_factor=delay ) adapter = HTTPAdapter(max_retries=retry_strategy) session.mount("https://", adapter) session.mount("http://", adapter) return session # Example usage if __name__ == "__main__": session = create_retry_session(retries=5, delay=10) try: response = session.post( "https://your-target-api.com/endpoint", json={"payload": "your-data"}, # Or use data= for form-encoded payloads timeout=30 ) response.raise_for_status() # Raise exception for non-2xx statuses (after retries) print("Request succeeded!", response.json()) except requests.exceptions.RequestException as e: print(f"All retries failed: {str(e)}")
Approach 2: Manual Retry Loop (Full Control Over Delays)
If you want precise fixed delays and full visibility into each retry attempt, a manual loop is perfect. This gives you complete control over when to retry and how long to wait.
import requests import time def post_with_fixed_retry(url, retries=5, delay=10, **kwargs): """ Send a POST request with retries on 503 errors, fixed delay between attempts. kwargs are passed directly to requests.post() (e.g., json, data, headers) """ for attempt in range(1, retries + 1): try: response = requests.post(url, timeout=30, **kwargs) # If we get a 503, log and wait before retrying if response.status_code == 503: print(f"Attempt {attempt}/{retries}: Got 503 Service Unavailable. Retrying in {delay}s...") time.sleep(delay) continue # Raise exception for other non-2xx statuses response.raise_for_status() return response except requests.exceptions.RequestException as e: print(f"Attempt {attempt}/{retries} failed: {str(e)}") if attempt < retries: print(f"Retrying in {delay}s...") time.sleep(delay) # If all retries fail, raise an exception raise Exception(f"Failed after {retries} retries. Last error: {str(e)}") # Example usage if __name__ == "__main__": try: response = post_with_fixed_retry( "https://your-target-api.com/endpoint", json={"payload": "your-data"}, headers={"Authorization": "Bearer your-token"} ) print("Success!", response.json()) except Exception as e: print(f"Final failure: {str(e)}")
Important Consideration: Idempotency
Before implementing retries for POST requests, make sure your request is idempotent—meaning sending it multiple times won’t cause unintended side effects (like duplicate orders or duplicate database entries). 503 errors usually mean the server didn’t process your request, so retries are safe in most cases, but always verify with your API’s documentation.
内容的提问来源于stack exchange,提问作者Phil Baines

