Selenium中undetected_chrome处理@字符异常问题求助
问题:undetected-chromedriver处理特殊字符异常
我在Python中使用Selenium标准Chrome驱动与undetected_chrome驱动,分别在正常浏览器模式和无头模式下测试时,发现异常行为:
- 标准Chrome驱动使用
send_keys()向HTML输入框发送特殊字符时表现正常; - undetected_chrome驱动的
send_keys()处理特殊字符存在问题:- 正常浏览器模式下,发送邮箱地址(如abc@xyz.com)时,@字符位置会被剪贴板当前内容替换(例如剪贴板内容为123时,会变成abc123xyz.com),因此我使用pyperclip预先将@复制到剪贴板作为临时解决方法;
- 无头模式下,该临时方法失效,@字符会被直接剥离,最终输入框内容为abcxyz.com。
我认为默认情况下发送@字符不应如此复杂,是否存在操作失误?现提出两个问题:
- 能否解释这些异常行为的原因?
- 如何在无头模式下使用undetected_chrome驱动正确发送邮箱地址?(因反爬需求必须使用该驱动)
使用的版本信息
- selenium==4.3.0
- undetected-chromedriver==3.1.5.post4
相关代码
标准Chrome驱动代码
from selenium import webdriver self.chrome_options = webdriver.ChromeOptions() if self.headless: self.chrome_options.add_argument('--headless') self.chrome_options.add_argument('--disable-gpu') prefs = {'download.default_directory' : os.path.realpath(self.download_dir_path)} self.chrome_options.add_experimental_option('prefs', prefs) self.driver = webdriver.Chrome(options=self.chrome_options)
undetected_chrome驱动代码
import undetected_chromedriver as uc # workaround for problem with pasting text from the clipboard into '@' symbol when using send_keys() import pyperclip pyperclip.copy('@') # <---- THIS IS THE WORKAROUND FOR THE PASTING PROBLEM self.chrome_options = uc.ChromeOptions() if self.headless: self.chrome_options.add_argument('--headless') self.chrome_options.add_argument('--disable-gpu') self.driver = uc.Chrome(options=self.chrome_options) params = { "behavior": "allow", "downloadPath": os.path.realpath(self.download_dir_path) } self.driver.execute_cdp_cmd("Page.setDownloadBehavior", params)
问题解答
1. 异常行为原因
- 正常模式下@被剪贴板内容替换:undetected-chromedriver为绕过反爬,对
send_keys()做了特殊的用户输入模拟,可能误将@的输入逻辑识别为粘贴操作(比如部分系统中@需要组合键输入,驱动模拟时触发了剪贴板粘贴,导致用剪贴板内容覆盖@)。 - 无头模式下@被剥离:无头Chrome环境中系统剪贴板权限被限制,pyperclip无法正常写入剪贴板;同时undetected-chromedriver在无头模式下的输入模拟逻辑存在兼容性bug,直接丢失了@字符。
2. 无头模式下的解决方案
方法一:用JavaScript直接设置输入框值
绕过send_keys()的输入模拟,直接通过JS修改输入框的value属性,不受特殊字符输入限制:
from selenium.webdriver.common.by import By email = "abc@xyz.com" # 替换为你实际的输入框定位方式,比如ID、XPath等 input_element = self.driver.find_element(By.ID, "email-input") self.driver.execute_script("arguments[0].value = arguments[1];", input_element, email)
方法二:升级undetected-chromedriver到最新版本
你当前使用的3.1.5.post4版本较旧,新版本大概率修复了特殊字符输入的bug,升级后直接使用send_keys()即可:
pip install --upgrade undetected-chromedriver
升级后代码无需剪贴板 workaround,直接执行:
input_element.send_keys("abc@xyz.com")
方法三:拆分输入内容或用ActionChains模拟按键
如果升级后仍有问题,可拆分邮箱内容逐个输入,或用ActionChains模拟@的组合键输入(根据你的键盘布局调整,比如美式键盘是Shift+2):
from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys # 拆分输入 input_element.send_keys("abc") # 模拟Shift+2输入@ ActionChains(self.driver).key_down(Keys.SHIFT).send_keys('2').key_up(Keys.SHIFT).perform() input_element.send_keys("xyz.com")
内容的提问来源于stack exchange,提问作者elaspog
相关产品推荐
相关产品推荐

