Python+Selenium用send_keys填充表单过慢,求更快替代方案
Hey there! I totally get the frustration of slow form filling—10 seconds for 7 fields is way too sluggish. Let’s walk through several practical optimizations to cut that time down drastically.
1. Use Faster Element Locators
Your current XPath queries work, but they’re not the most efficient. Since you’re targeting elements by their unique id attribute, skip XPath parsing entirely and use direct ID locators. This reduces the time Selenium spends searching the DOM for each element.
Bad (slow):
driver.find_element_by_xpath("//*[@id='order_billing_name']").send_keys("John Doe")
Good (fast):
driver.find_element_by_id("order_billing_name").send_keys("John Doe")
Even better: Fetch all required elements in one go to avoid repeated DOM traversals:
# Grab all elements first fields = { "billing_name": driver.find_element_by_id("order_billing_name"), "email": driver.find_element_by_id("order_email"), "tel": driver.find_element_by_id("order_tel"), # Add the rest of your fields here } # Fill them in bulk fields["billing_name"].send_keys("John Doe") fields["email"].send_keys("supreme@gmail.com") fields["tel"].send_keys("012-345-6789")
2. Replace send_keys with JavaScript Direct Value Setting
The send_keys method simulates real user keystrokes, which adds intentional delays (to mimic human input). If you don’t need to trigger keyboard-specific events (like onkeydown or onkeyup), use JavaScript to directly set the element’s value attribute. This is almost instant.
Basic JS Method (no event triggers):
def set_field(driver, element_id, value): driver.execute_script(f"document.getElementById('{element_id}').value = '{value}';") # Usage set_field(driver, "order_billing_name", "John Doe") set_field(driver, "order_email", "supreme@gmail.com")
JS Method with Event Triggers (if form needs validation):
Some forms rely on input or change events to trigger validation. In that case, dispatch the event after setting the value:
def set_field_with_event(driver, element_id, value): driver.execute_script(f""" const elem = document.getElementById('{element_id}'); elem.value = '{value}'; elem.dispatchEvent(new Event('input')); // Trigger input event """)
3. Optimize Wait Strategies
Unnecessary waits are a huge time drain. Avoid using a long global implicitly_wait unless absolutely necessary. Instead, use explicit waits to only wait for the elements you need, with a tight timeout.
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # Wait up to 2 seconds for each required element to be present wait = WebDriverWait(driver, 2) wait.until(EC.presence_of_element_located((By.ID, "order_billing_name"))) wait.until(EC.presence_of_element_located((By.ID, "order_email"))) # Now fill the form—no more waiting around!
4. Disable Unnecessary Browser Features
Cut down on page load time by disabling resource-heavy features like images, extensions, or using headless mode (no visible browser window).
from selenium import webdriver from selenium.webdriver.chrome.options import Options options = Options() options.add_argument("--headless=new") # Headless mode (faster, no UI) options.add_argument("--disable-images") # Disable image loading options.add_argument("--disable-extensions") # Disable browser extensions options.add_argument("--disable-plugins") # Disable plugins driver = webdriver.Chrome(options=options)
5. Batch Form Submission (If Possible)
If the form uses standard HTML without complex JS dependencies, you could even submit the form directly via a POST request using requests instead of Selenium. This skips the entire browser rendering process, but only works if you don’t need to interact with JS-driven elements (like captchas or dynamic fields).
Example with requests:
import requests form_data = { "order[billing_name]": "John Doe", "order[email]": "supreme@gmail.com", "order[tel]": "012-345-6789", # Add other form fields here (check the form's `name` attributes) } response = requests.post("https://your-form-url.com/submit", data=form_data)
Final Results
Combining these optimizations—especially using JS for value setting and faster locators—should bring your form filling time down to under 1 second, which is way more than acceptable.
内容的提问来源于stack exchange,提问作者Joe Cook

