使用Selenium绕过Taylor & Francis人机验证时遇元素定位错误求助
解决Taylor & Francis网站Selenium登录与反爬问题
一、绕过人机验证的可行方案
- 使用undetected-chromedriver替代原生Selenium:这个库专门修改了ChromeDriver的特征,能避开网站的自动化检测。安装命令:
pip install undetected-chromedriver,初始化时匹配你的Chrome版本(114):import undetected_chromedriver as uc driver = uc.Chrome(version_main=114) driver.get("https://www.tandfonline.com/loi/nvpp20") - 添加浏览器启动参数,模拟真实用户环境:
from selenium.webdriver.chrome.options import Options options = Options() options.add_argument("--disable-blink-features=AutomationControlled") options.add_argument("--start-maximized") options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.199 Safari/537.36") options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option('useAutomationExtension', False) - 手动验证(临时应急方案):如果自动化方案失效,在代码中加入等待时间,手动完成人机验证后再继续:
import time driver.get("https://www.tandfonline.com/loi/nvpp20") time.sleep(30) # 这段时间手动完成验证操作
二、解决NoSuchElementException定位登录元素问题
- 用显式等待替代直接定位:确保元素完全加载后再操作,避免因页面渲染延迟导致的定位失败:
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 最长等待10秒,直到登录元素出现 login_btn = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, "你的登录元素XPATH")) ) login_btn.click() - 检查是否存在iframe:如果登录表单嵌套在iframe内,必须先切换到iframe再定位元素:
# 先定位并切换到目标iframe iframe = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "实际iframe的ID")) ) driver.switch_to.frame(iframe) # 之后再定位登录元素 - 优化定位方式:避免使用过于绝对的XPATH,改用更稳定的属性(如id、class)。例如登录按钮class为
login-btn时:login_btn = driver.find_element(By.CLASS_NAME, "login-btn")
三、其他防封禁注意事项
- 模拟真实用户行为:添加随机等待时间,避免连续高频请求:
import random time.sleep(random.uniform(2, 5)) - 保存登录Cookie:成功登录后将Cookie本地存储,后续启动浏览器直接加载,减少重复登录和验证:
import pickle # 登录后保存Cookie with open("tandf_cookies.pkl", "wb") as f: pickle.dump(driver.get_cookies(), f) # 下次启动时加载Cookie driver.get("https://www.tandfonline.com/loi/nvpp20") with open("tandf_cookies.pkl", "rb") as f: cookies = pickle.load(f) for cookie in cookies: driver.add_cookie(cookie) driver.refresh()
内容的提问来源于stack exchange,提问作者Ido Kobi
相关产品推荐
相关产品推荐

