使用Selenium+undetected_chromedriver登录期刊网站遭拦截,无法进入密码页求助
问题描述
我编写了以下通过机构权限登录期刊网站的代码:
import pandas as pd import requests from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import Select import undetected_chromedriver as uc import time import os output = pd.read_excel("C:\\Users\\97254\\Downloads\\output.xlsx") url = "https://www.tandfonline.com/loi/nvpp20" driver = uc.Chrome() driver.maximize_window() driver.get(url) time.sleep(5) driver.find_element(By.CLASS_NAME,"sign-in-link").click() time.sleep(5) driver.find_element("tag name","a").find_element("xpath",'//*[@id="frmLogin"]/div[2]/ul/li/a').click() time.sleep(3) elem = driver.find_element("xpath",'//*[@id="shibboleth_search"]/div/input').send_keys("Bar-Ilan University")
执行代码后,Chrome浏览器被网站踢出,未能进入密码验证页面,Python端出现报错(见截图)。请问是否因使用undetected_chromedriver库导致该问题?如何解决以进入密码验证环节?
问题分析与解决方法
1. 是否是undetected_chromedriver的问题?
大概率不是该库本身的问题——undetected_chromedriver正是用来规避网站反爬检测的工具。问题核心出在代码逻辑缺陷和机械操作节奏被反爬识别:
- 链式元素定位
driver.find_element("tag name","a").find_element(...)极易出错,第一个<a>标签未必是目标元素,定位错误会直接触发异常 - 固定
time.sleep()完全依赖硬编码等待时间,网络波动时要么等待不足导致元素未加载,要么等待过长暴露非人类操作 - 缺少基于元素状态的显式等待,网站反爬机制会识别出机械的操作节奏
2. 具体解决步骤
(1)修复元素定位逻辑
删除链式定位,直接显式等待并定位目标元素:
原错误代码:
driver.find_element("tag name","a").find_element("xpath",'//*[@id="frmLogin"]/div[2]/ul/li/a').click()
替换为:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="frmLogin"]/div[2]/ul/li/a'))).click()
(2)用显式等待替换所有固定sleep
所有time.sleep()都替换为基于元素状态的等待,模拟自然操作节奏:
# 打开页面后,等待登录链接出现 driver.get(url) WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "sign-in-link"))) # 点击登录后,等待机构登录选项出现 driver.find_element(By.CLASS_NAME,"sign-in-link").click() WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//*[@id="frmLogin"]/div[2]/ul/li/a'))) # 点击机构登录后,等待搜索框可输入 WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="shibboleth_search"]/div/input'))).send_keys("Bar-Ilan University")
(3)优化undetected_chromedriver初始化配置
添加模拟真实浏览器的参数,降低被检测概率:
options = uc.ChromeOptions() # 禁用自动化特征检测 options.add_argument("--disable-blink-features=AutomationControlled") # 填入你日常使用Chrome的UA(浏览器输入about:version可查看) options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") # 启用缓存和本地存储,模拟真实用户会话 options.add_argument("--enable-local-storage") options.add_argument("--enable-session-storage") driver = uc.Chrome(options=options) driver.maximize_window()
(4)补充人类操作细节
输入机构名称后,模拟按下回车键触发搜索,而非仅输入文本:
search_input = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="shibboleth_search"]/div/input'))) search_input.send_keys("Bar-Ilan University") search_input.send_keys(Keys.ENTER)
(5)添加异常处理逻辑
用try-except块捕获定位失败异常,增加容错性:
from selenium.common.exceptions import TimeoutException, NoSuchElementException def safe_click(driver, by, value, timeout=10): try: element = WebDriverWait(driver, timeout).until(EC.element_to_be_clickable((by, value))) element.click() return True except (TimeoutException, NoSuchElementException): print(f"无法定位元素:{by}={value}") return False # 使用示例 safe_click(driver, By.CLASS_NAME, "sign-in-link") safe_click(driver, By.XPATH, '//*[@id="frmLogin"]/div[2]/ul/li/a')
内容的提问来源于stack exchange,提问作者Ido Kobi
相关产品推荐
相关产品推荐

