如何使用Python Requests而非Selenium处理含onclick JavaScript提交函数的HTML表单
Got it, let's break down how to replicate that JavaScript-powered form submission using Python's Requests library—no Selenium needed! We'll walk through exactly what the JS function does, then translate that logic into Python code.
Step 1: Understand the JavaScript Workflow
First, let's unpack what createUserSearchURL does when you click the Search button:
- Validates the form (we can skip explicit validation if we know we're sending valid data)
- Collects all filled
.searchinputs, appending their names/values as GET parameters to the original form action - Builds a
filter-clausestring to send to a backend check endpoint - Makes a synchronous AJAX call to
/homepage-5.2.3.1/html/homepage/checkUsers.jspwith that filter clause - If the response returns
directRedirect: true, it swaps the form action to the 360view URL with user-specific parameters; otherwise, uses the modified original action - Finally, submits the form to the updated action URL
Step 2: Replicate This with Python Requests
First, make sure you have requests installed (pip install requests). We'll use a persistent session to maintain authenticated cookies (critical for CRM access).
1. Set Up Authenticated Session
CRM systems require logged-in sessions, so start by logging in (adjust the login details to match your CRM's actual login endpoint):
import requests from urllib.parse import urlencode, quote import time # Create a persistent session to keep login cookies session = requests.Session() # Example login flow (replace with your CRM's login URL and form fields) login_url = "https://crm.spectranet.com.ng/login" login_payload = { "username": "your_crm_username", "password": "your_crm_password" } # Send login request login_response = session.post(login_url, data=login_payload) # Verify login succeeded (check for a 200 status or a specific cookie) if login_response.status_code != 200: raise Exception("Login failed—check credentials or login endpoint")
2. Define Your Search Parameters
Fill in the fields you want to search for (match the name attributes from the original form):
# Define search fields (leave empty fields blank) search_fields = { "userId": "", # User ID field "email": "", # Primary Email "userdetails.mobile": "", # Primary Mobile Number "imsi": "", # IMSI "msisdn": "", # MSISDN "subscriptions.customfield1": "" # IMEI field } # Filter out empty fields to avoid unnecessary parameters filled_fields = {k: v.strip() for k, v in search_fields.items() if v.strip()}
3. Build the Filter Clause
Replicate the JS logic to create the filter-clause string for the AJAX check:
filter_clause = "AND 1=1" for field_name, value in filled_fields.items(): # Properly encode special characters in the value encoded_value = quote(value) if field_name == "userId": # Use LIKE clause for userId (matches starts-with pattern) filter_clause += f" AND {field_name} like '{encoded_value}%'" else: # Use exact match for other fields filter_clause += f" AND {field_name} = '{encoded_value}'"
4. Call the Check Users Endpoint
Send the filter clause to the AJAX endpoint and process the response:
check_users_url = "https://crm.spectranet.com.ng/homepage-5.2.3.1/html/homepage/checkUsers.jsp" check_params = {"filter-clause": filter_clause} # Send GET request to check users endpoint check_response = session.get(check_users_url, params=check_params) check_data = check_response.json() # Define base URLs from the original JS original_action = "https://crm.spectranet.com.ng/group/admin/add-end-customer?p_p_id=customerdetails_WAR_ase5231&p_p_lifecycle=0&p_p_state=normal&p_p_col_id=column-1&p_p_col_count=2&_customerdetails_WAR_ase5231_struts_action=%2Fase%2Fcustomerdetails_view&_customerdetails_WAR_ase5231_CMD=view" redirect_url = "https://crm.spectranet.com.ng/group/admin/360view?p_p_id=customerview_WAR_ase5231&p_p_lifecycle=0&p_p_state=normal&p_p_col_id=column-1&p_p_col_count=2&_customerview_WAR_ase5231_struts_action=%2Fase%2Fcustomerview_action&_customerview_WAR_ase5231_CMD=view" # Determine final action URL final_action = original_action if check_data.get("directRedirect") is True: # Build redirect parameters from the response redirect_params = { "userIndex": check_data["userIndex"], "_customerview_WAR_ase5231_recId": check_data["userIndex"], "userId": check_data["userId"], "refreshTime": str(int(time.time() * 1000)) # Use current timestamp instead of static value } # Append params to redirect URL final_action = f"{redirect_url}&{urlencode(redirect_params)}" else: # Append filled search fields to original action URL final_action = f"{original_action}&{urlencode(filled_fields)}"
5. Submit the Form
Finally, send the POST request to the final action URL (matching the original form's POST method):
# Submit the form data submit_response = session.post(final_action, data=filled_fields) # Verify submission success print(f"Submission Status Code: {submit_response.status_code}") # If you need to parse the results, use BeautifulSoup # from bs4 import BeautifulSoup # soup = BeautifulSoup(submit_response.content, "html.parser") # Extract search results from the soup object
Key Tips
- Session Persistence: Always use
requests.Session()to maintain login cookies—without this, your CRM will reject unauthenticated requests. - Parameter Encoding: Use
quoteandurlencodeto handle special characters (like spaces or symbols) in search values. - Timestamp: The original JS uses a static
refreshTime; replacing it with a current timestamp ensures compatibility with any server-side checks. - Error Handling: Add try/except blocks around requests to handle network errors, invalid JSON responses, or login failures.
内容的提问来源于stack exchange,提问作者Era Osa

