如何使用Undetected Chrome Driver实现无需等待页面完全加载即可上传文件?
实现无需等待页面完全加载的文件上传(undetected-chromedriver + Selenium)
问题描述
我正在结合undetected_chromedriver与Selenium执行涉及文件上传的网页爬虫任务,但发现程序会等待页面完全加载后才允许执行文件上传操作。我希望在文件输入元素一出现就上传文件,无需等待页面全部加载完成,尝试设置pageload = eager但未达到预期效果,请问该如何实现?
用户提供的代码:
import os from selenium.webdriver.common.by import By from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import undetected_chromedriver as uc import time import datetime #Server from flask import Flask, request, jsonify from . import app UPLOAD_DIR = 'upload/' # Specify the upload directory here @app.route('/', methods=['POST']) def handle_audio_blob(): audio_blob = request.data current_datetime = datetime.datetime.now() formatted_datetime = current_datetime.strftime("%Y-%m-%d-%H-%M-%S") # Save the audio_blob to the upload directory file_name = f'audio_capture_{formatted_datetime}.wav' file_path = os.path.join(UPLOAD_DIR, file_name) with open(file_path, 'wb') as f: f.write(audio_blob) options = uc.ChromeOptions() options.headless = False driver = uc.Chrome(driver_executable_path=ChromeDriverManager().install(), options=options) # Open the URL driver.get("https://tunebat.com/Analyzer") time.sleep(1) absolute_file_path = os.path.abspath(file_path) print(absolute_file_path) # Locate and interact with the file input element file_input = driver.find_element(By.XPATH, "//input[@type='file']") file_input.send_keys(absolute_file_path) wait = WebDriverWait(driver, 30) # Wait up to 30 seconds wait.until(EC.presence_of_element_located((By.XPATH, "//main/div/div[3]/div/div[2]/div"))) time.sleep(1) key = driver.find_element(By.XPATH, "//main/div/div[3]/div/div[2]/div/div[2]/div/div[1]/div/span[2]/div") bpm = driver.find_element(By.XPATH, "//main/div/div[3]/div/div[2]/div/div[2]/div/div[1]/div/span[4]/div") result = { "key": key.text, "bpm": bpm.text } print(result) # Close the browser driver.quit() if os.path.exists(file_path): os.remove(file_path) return jsonify(result)
解决方案
1. 正确配置页面加载策略
pageload = eager需正确配置到ChromeOptions中,确保参数生效:
options = uc.ChromeOptions() options.page_load_strategy = 'eager' # 仅等待DOM加载完成,无需等待图片、样式等资源加载 options.headless = False
2. 用显式等待替代固定延迟
移除time.sleep(1),改用WebDriverWait监听文件输入元素的出现,一旦元素可定位就立即执行上传:
# 打开页面后直接等待文件输入元素 wait = WebDriverWait(driver, 10) file_input = wait.until(EC.presence_of_element_located((By.XPATH, "//input[@type='file']"))) file_input.send_keys(absolute_file_path)
3. 优化后的完整代码
import os from selenium.webdriver.common.by import By from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import undetected_chromedriver as uc import datetime #Server from flask import Flask, request, jsonify from . import app UPLOAD_DIR = 'upload/' # Specify the upload directory here @app.route('/', methods=['POST']) def handle_audio_blob(): audio_blob = request.data current_datetime = datetime.datetime.now() formatted_datetime = current_datetime.strftime("%Y-%m-%d-%H-%M-%S") # Save the audio_blob to the upload directory file_name = f'audio_capture_{formatted_datetime}.wav' file_path = os.path.join(UPLOAD_DIR, file_name) with open(file_path, 'wb') as f: f.write(audio_blob) options = uc.ChromeOptions() options.page_load_strategy = 'eager' # 配置eager加载策略 options.headless = False driver = uc.Chrome(driver_executable_path=ChromeDriverManager().install(), options=options) # Open the URL driver.get("https://tunebat.com/Analyzer") absolute_file_path = os.path.abspath(file_path) print(absolute_file_path) # 显式等待文件输入元素出现后立即上传 wait = WebDriverWait(driver, 10) file_input = wait.until(EC.presence_of_element_located((By.XPATH, "//input[@type='file']"))) file_input.send_keys(absolute_file_path) # 等待分析结果元素加载 wait.until(EC.presence_of_element_located((By.XPATH, "//main/div/div[3]/div/div[2]/div"))) key = driver.find_element(By.XPATH, "//main/div/div[3]/div/div[2]/div/div[2]/div/div[1]/div/span[2]/div") bpm = driver.find_element(By.XPATH, "//main/div/div[3]/div/div[2]/div/div[2]/div/div[1]/div/span[4]/div") result = { "key": key.text, "bpm": bpm.text } print(result) # Close the browser driver.quit() if os.path.exists(file_path): os.remove(file_path) return jsonify(result)
关键说明
eager加载策略会在DOMContentLoaded事件触发后停止等待,此时页面核心元素已可交互,能大幅缩短等待时间。- 显式等待是Selenium中最可靠的等待机制,相比固定延迟
time.sleep(),能在目标元素出现的第一时间执行操作,避免无效等待。
内容的提问来源于stack exchange,提问作者Lee Huat Chong
相关产品推荐
相关产品推荐

