如何解决Python+requests发送POST请求时出现的403错误(附代码示例)
Let’s break down the likely reasons you’re hitting a 403 Forbidden error, even after including Chrome’s headers and all form data:
1. Invalid or Stale CSRF Token
Your code uses a hardcoded _csrf value, but CSRF tokens are session-bound and short-lived. Using an old token (like the one from yesterday’s code) or a token not tied to your active session will immediately trigger a server rejection.
Fix: Always fetch the latest CSRF token directly from the login page before sending your POST request. Use a parser like BeautifulSoup to extract it from the page’s HTML.
2. Mismanaged Cookies
You’re manually setting a Cookie header with the placeholder value "cookie", which overrides the requests.Session()’s automatic cookie management. Servers rely on consistent session cookies to validate requests—mismatched or invalid cookies will result in 403.
Fix: Let requests.Session() handle cookies automatically. First send a GET request to the login page to capture the initial session cookies, then the POST request will reuse them seamlessly.
3. Redundant or Incorrect Request Headers
Content-Length: Manually setting this is risky—if the actual size of yourdatadoesn’t match the value you provided, the server will reject the request. Remove this header entirely;requestscalculates it automatically.Host: YourHostis set to"test"whileOriginis"test.ru"—these values must match. Delete theHostheader;requestsgenerates it correctly from the target URL.
4. Missing Hidden Fields or JS-Generated Parameters
Some websites include hidden form fields (like __VIEWSTATE in ASP.NET) or use JavaScript to encrypt data (e.g., password hashing) before submission. If you’re missing these fields or submitting unencrypted data when the server expects encrypted values, you’ll get a 403.
Check: Inspect your browser’s Network tab during a manual login—compare the form data you’re sending to what the browser actually posts. Replicate any extra fields or encryption logic in your code.
Modified Working Example Code
Here’s how to adjust your code to fix the above issues:
import requests from bs4 import BeautifulSoup base_url = 'https://test.ru' login_page_url = f"{base_url}/sign" # Initialize session to handle cookies automatically session = requests.Session() # Step 1: Fetch login page to get fresh CSRF token and session cookies login_page_response = session.get(login_page_url) soup = BeautifulSoup(login_page_response.text, 'html.parser') csrf_token = soup.find('input', attrs={'name': '_csrf'}).get('value') # Step 2: Prepare form data with the new CSRF token form_data = { 'username': 'admin', 'password': 'q1', 'remember-me': '1', '_csrf': csrf_token } # Step 3: Clean up headers (remove redundant/incorrect entries) request_headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7', 'Cache-Control': 'max-age=0', 'Connection': 'keep-alive', 'Content-Type': 'application/x-www-form-urlencoded', 'Origin': base_url, 'Referer': login_page_url, 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36' } # Step 4: Send POST request with valid session cookies and CSRF token login_response = session.post(base_url, data=form_data, headers=request_headers) # Verify the result print(f"Status Code: {login_response.status_code}") print(f"Response Preview: {login_response.text[:500]}") # Print first 500 characters of the response
Additional Checks If the Issue Persists
- IP Blocking: If you’ve made multiple failed attempts, the site might have blocked your IP. Try switching networks or using a proxy.
- Captcha Requirements: Some sites trigger captchas after suspicious activity. If you see a captcha in the login page response, you’ll need to implement captcha solving (e.g., using OCR services).
- Strict UA Validation: Double-check that your User-Agent matches exactly what Chrome sends—some sites enforce strict UA checks.
- Correct POST URL: Ensure the POST URL matches the
actionattribute of the login form in the HTML (sometimes it’s a relative path that needs to be converted to a full URL).
内容的提问来源于stack exchange,提问作者Fedor March

