我遇到了硒显式等待按钮可点击的问题。当按钮 web 元素由
返回时self.driver_wait.until(
expected_conditions.element_to_be_clickable((By.ID, 'login-btn'))
)
我收到阻塞错误:
selenium.common.exceptions.ElementClickInterceptedException: Message: Element <a id="login-btn" class="fm-btn fm-btn-ghost-white account"> is not clickable at point (886,96) because another element <div id="ot-pc-content" class="ot-pc-scrollbar"> obscures it
讽刺的是,它明确指出,该元素不可点击,尽管显式等待指令应该完全等待我的理解......
我尝试等到阻碍元素不再可见,但这没有帮助:
self.driver_wait.until(
expected_conditions.invisibility_of_element((By.ID, 'ot-pc-content'))
)
button_login_1 = self.driver_wait.until(
expected_conditions.element_to_be_clickable((By.ID, 'login-btn'))
)
我想使用这个最小示例可以重现这种行为,其中包括类定义所需的所有内容:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
import time
import datetime as dt
from typing import Union
class Session_FLM:
def __init__(self,
url: str = 'https://www.freelancermap.de/',
browser: str = "FireFox",
session_time: Union[None, dt.datetime] = None,
use_fixed_wait_default: bool = False,
default_wait_time_fixed: float = 1,
default_explicit_wait_max: float = 10,
implicit_wait_max: float = 10
):
self.browser: str = browser
if session_time:
self.session_time = session_time
else:
self.session_time = dt.datetime.now()
self.url: str = url
self.cookies: bool = False
self.default_explicit_wait_max: float = default_explicit_wait_max
self.use_fixed_wait_default: bool = use_fixed_wait_default
self.default_wait_time_fixed: float = default_wait_time_fixed
self.implicit_wait_max: float = implicit_wait_max
self.driver: Union[
webdriver.firefox.webdriver.WebDriver,
webdriver.chrome.webdriver.WebDriver,
None] = None
self.driver_wait: Union[WebDriverWait, None] = None
self.headers: dict = {
'User-Agent': 'Mozilla/5.0'
}
def init_webdriver(
self,
url: Union[str, None] = None,
use_fixed_wait: Union[bool, None] = None,
wait_time_fixed: Union[float, None] = None,
activate_implicit_wait: bool = False,
implicit_wait_max: Union[float, None] = None,
explicit_wait_max: Union[float, None] = None
) -> None:
if not url:
url = self.url
if not use_fixed_wait:
use_fixed_wait = self.use_fixed_wait_default
if not wait_time_fixed:
wait_time_fixed = self.default_wait_time_fixed
if not implicit_wait_max:
implicit_wait_max = self.implicit_wait_max
if not explicit_wait_max:
explicit_wait_max = self.default_explicit_wait_max
if self.browser == 'Chrome':
driver_options = webdriver.ChromeOptions()
driver_options.page_load_strategy = 'normal' # wait for entire page content to be loaded
self.driver = webdriver.Chrome(options=driver_options)
elif self.browser == 'FireFox':
driver_options = webdriver.FirefoxOptions()
driver_options.page_load_strategy = 'normal' # wait for entire page content to be loaded
self.driver = webdriver.Firefox(options=driver_options)
self.driver_wait = WebDriverWait(self.driver, explicit_wait_max)
if activate_implicit_wait:
self.driver.implicitly_wait(implicit_wait_max)
self.driver.get(url=url)
if use_fixed_wait:
time.sleep(wait_time_fixed)
def cookies_handling(
self,
accept_cookies: bool = False,
use_fixed_wait: Union[bool, None] = None,
wait_time_fixed: Union[float, None] = None
) -> None:
"""
Handle freelancermap cookies.
Args:
accept_cookies (bool, optional): True: Accept all cookies; False: Enter cookie details and only accept obigatory cookies.
use_fixed_wait: (Union[bool, None], optional): Only use fixed wait if True
wait_time_fixed (Union[float, None], optional): Fixed waiting time, which is used whenever "Selenium Implicit Wait" is set to be inactive; overrides "Session_FLM" objects default fixed waiting time.
"""
if not use_fixed_wait:
use_fixed_wait = self.use_fixed_wait_default
if not wait_time_fixed:
wait_time_fixed = self.default_wait_time_fixed
if accept_cookies:
button_accept_cookies = self.driver_wait.until(
expected_conditions.element_to_be_clickable((By.ID, 'onetrust-accept-btn-handler'))
)
button_accept_cookies.click()
else:
button_settings_cookies = self.driver_wait.until(
expected_conditions.element_to_be_clickable((By.ID, 'onetrust-pc-btn-handler'))
)
button_settings_cookies.click()
if use_fixed_wait:
time.sleep(wait_time_fixed)
button_accept_selected_cookies = self.driver_wait.until(
expected_conditions.element_to_be_clickable((By.CLASS_NAME, 'save-preference-btn-handler'))
)
button_accept_selected_cookies.click()
if use_fixed_wait:
time.sleep(wait_time_fixed)
def login(
self,
email: str,
password: str,
use_fixed_wait: Union[bool, None] = None,
wait_time_fixed: Union[float, None] = None
) -> None:
"""
Login with an existing freelancermap account.
Args:
email (str): Account email
password (str): Account password
use_fixed_wait: (Union[bool, None], optional): Only use fixed wait if True
wait_time_fixed(Union[float, None], optional): Fixed waiting time, which is used whenever "Selenium Implicit Wait" is set to be inactive; overrides "Session_FLM" objects default fixed waiting time.
"""
if not wait_time_fixed:
wait_time_fixed = self.default_wait_time_fixed
if use_fixed_wait:
time.sleep(wait_time_fixed)
self.driver_wait.until(
expected_conditions.invisibility_of_element((By.ID, 'ot-pc-content'))
)
button_login_1 = self.driver_wait.until(
expected_conditions.element_to_be_clickable((By.ID, 'login-btn'))
)
button_login_1.click()
if use_fixed_wait:
time.sleep(wait_time_fixed)
input_field_email = self.driver.find_element(
By.ID,
"login"
)
input_field_email.send_keys(email)
input_field_pw = self.driver.find_element(
By.ID,
"password"
)
input_field_pw.send_keys(password)
button_login_2 = self.driver_wait.until(
expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, 'button.fm-btn-primary:nth-child(1)'))
)
button_login_2.submit()
self.driver_wait.until(
expected_conditions.url_to_be('https://www.freelancermap.de/mein_account.html')
)
if use_fixed_wait:
time.sleep(wait_time_fixed)
self.driver.back()
if use_fixed_wait:
time.sleep(wait_time_fixed)
if __name__ == '__main__':
flm = Session_FLM(
url='https://www.freelancermap.de/projektboerse.html',
default_wait_time_fixed=2
)
flm.init_webdriver(activate_implicit_wait=False)
flm.cookies_handling(
accept_cookies=False,
use_fixed_wait=False)
flm.login(
email='abc',
password='123',
use_fixed_wait=False
)
cookies_handling()
调用 use_fixed_wait=True
时,单击按钮即可工作。login()
调用 use_fixed_wait=True
时,单击按钮即可工作。cookies_handling()
调用 accept_cookies=False
时,单击按钮有效,因为在这种情况下,阻碍元素根本不会出现。False
时,单击按钮会失败。我真的很想了解我的方法有什么问题以及如何在不添加
time.sleep()
的情况下应对它。
这是您作为 MCVE 应该发布的内容,
url = 'https://www.freelancermap.de/projektboerse.html'
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(url)
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.ID, "login-btn"))).click()
代码的其余部分与错误无关,只会造成混乱并混淆问题。
这段代码在我的机器上运行得很好。从点击拦截异常提供的 HTML 来看,您的代码所点击的似乎是 cookie 横幅。我的建议是首先接受或以其他方式关闭 cookie 横幅,然后继续执行其余代码,您应该不会遇到任何问题。