You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Selenium登录WSJ时输入密码触发TimeoutException异常问题

问题根因定位

该TimeoutException报错是因为WebDriverWait等待10秒后,仍未找到ID为password的可点击元素,常见触发原因有三类:

  1. 点击继续按钮后,密码输入框处于iframe或shadow DOM嵌套结构中,直接按全局ID查找无法命中对应元素
  2. WSJ反爬机制识别到Selenium自动化浏览器特征,拦截了登录流程跳转,未正常加载密码输入模块
  3. 页面加载延迟超过预设等待时长,或是密码输入框的实际ID/属性发生了更新,和定位规则不匹配
修复方案
  • 第一步:初始化Chrome时添加反爬特征隐藏配置,避免被站点反爬规则拦截
from selenium import webdriver
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

chrome_options = Options()
# 隐藏自动化浏览器特征
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option("useAutomationExtension", False)
driver = webdriver.Chrome(ChromeDriverManager().install(), options=chrome_options)
# 覆盖navigator.webdriver属性规避检测
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source": """
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined
        })
    """
})
  • 第二步:替换固定time.sleep为显式等待,同时检查iframe嵌套情况,调整元素定位逻辑
url = 'https://www.wsj.com/news/archive/years'
user1 = 'USERNAME'
pass1 = 'PASSWORD'

driver.get(url)
# 点击登录按钮
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, 'Sign In'))).click()
# 输入用户名
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, 'username'))).send_keys(user1)
# 点击继续按钮,class用部分匹配规则,避免页面样式更新导致定位失效
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'continue-submit')]"))).click()

# 先检查是否存在嵌套密码框的iframe,可先运行打印iframe列表确认ID
iframes = driver.find_elements(By.TAG_NAME, 'iframe')
for iframe in iframes:
    print(iframe.get_attribute('id'))
# 确认密码框所在iframe后,先切换到对应iframe再定位元素,示例如下:
# driver.switch_to.frame('替换为实际的iframeID')

# 延长等待时长至20秒,先定位可见元素再操作
password = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.ID, 'password')))
# 先点击激活输入框再输入内容
password.click()
password.send_keys(pass1)

# 如果之前切换了iframe,输入完成后切回默认文档
# driver.switch_to.default_content()

# 点击提交按钮
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'basic-login-submit')]"))).click()
  • 第三步:如果ID定位仍失效,可替换为通用属性定位,比如By.CSS_SELECTOR, "input[type='password']",不绑定固定ID适配页面更新
  • 注意你贴出的代码中XPath表达式用了HTML转义字符",实际运行时需要替换为普通双引号,否则会触发语法错误。
  • 你当前使用的find_element_by_id这类方法在Selenium 4.0+版本已被废弃,建议统一替换为driver.find_element(By.XXX, 定位符)的写法,避免版本兼容问题。

内容的提问来源于stack exchange,提问作者Tad Ye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:57:03