如何模拟浏览器发送POST请求实现dsbmobile.de自动登录并获取文件
Hey there! The issue you're facing is super common with ASP.NET-based websites like DSB Mobile—they rely on hidden form fields (like __EVENTVALIDATION and __VIEWSTATE) to validate requests, plus they expect request headers that mimic a real browser. Let's break down how to fix your script step by step:
Why Your Current Code Fails
When you send a POST directly without first fetching the login page, you're missing critical hidden fields that the server generates dynamically for each session. These fields are part of ASP.NET's view state system, which prevents invalid or tampered requests. The server rejects your POST because it doesn't recognize these missing values, so it just sends the login page back again.
Step 1: Fetch the Login Page First to Get Hidden Fields
You need to first send a GET request to the login page to retrieve the hidden form fields and establish a session cookie. We'll use BeautifulSoup to parse the HTML and extract these values easily.
First, install beautifulsoup4 if you haven't already:
pip install beautifulsoup4
Step 2: Use a Session to Persist Cookies
Using requests.Session() will automatically handle cookies for you, which is essential because the server uses cookies to track your session between the GET and POST requests.
Step 3: Construct the Full POST Payload
Include all the hidden fields you extracted, plus your credentials. You'll also need to set proper request headers to mimic a browser.
Full Working Script Example
import requests from bs4 import BeautifulSoup # Initialize a session to persist cookies session = requests.Session() # Login URL login_url = "https://www.dsbmobile.de/Login.aspx?ReturnUrl=%2f" # Step 1: GET the login page to get hidden fields and cookies response = session.get(login_url) soup = BeautifulSoup(response.text, "html.parser") # Extract all necessary hidden fields payload = { "__VIEWSTATE": soup.find("input", {"id": "__VIEWSTATE"})["value"], "__VIEWSTATEGENERATOR": soup.find("input", {"id": "__VIEWSTATEGENERATOR"})["value"], "__EVENTVALIDATION": soup.find("input", {"id": "__EVENTVALIDATION"})["value"], "txtUser": "your_username_here", # Replace with your actual username "txtPass": "your_password_here", # Replace with your actual password "__EVENTTARGET": "", # Usually empty for initial login "__EVENTARGUMENT": "" # Usually empty for initial login } # Step 2: Set headers to mimic a browser headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Referer": login_url, "Content-Type": "application/x-www-form-urlencoded" } # Step 3: Send the POST request to login login_response = session.post(login_url, data=payload, headers=headers) # Verify if login was successful # You can check by accessing a protected page, like the dashboard dashboard_url = "https://www.dsbmobile.de/" dashboard_response = session.get(dashboard_url) # Print the dashboard content to confirm print(dashboard_response.text)
Key Notes to Keep in Mind
- Always fetch the login page first: The hidden fields change with each session, so you can't hardcode them—you need to extract them dynamically every time you run the script.
- Mimic browser headers: The
User-Agentheader tells the server you're using a real browser. Without it, some servers block requests. TheRefererheader lets the server know you came from the login page, which is part of normal browser behavior. - Session persistence: Using
requests.Session()ensures that cookies from the GET request are carried over to the POST request, which is required to maintain your session state. - Check for additional fields: Sometimes ASP.NET forms have extra hidden fields (like
__EVENTTARGET). Inspect the login form's HTML to make sure you're including all required inputs.
If you still run into issues, try inspecting the network request your browser makes when you log in (using Chrome DevTools or Firefox Developer Tools). Look at the "Form Data" section of the POST request—this will show you exactly which fields the server expects, so you can match them in your payload.
内容的提问来源于stack exchange,提问作者unnamed-dev

