簡體   English   中英

Python Selenium 元素點擊攔截

[英]Python Selenium element click intercepted

我試圖讓 Selenium 點擊一個鏈接,但它給出了一個錯誤,說“點擊被攔截”。

該代碼確實工作過一次並加載了正確的網頁,但此后我一直沒有讓它工作。 Selenium 確實找到了要單擊的鏈接,但它不想使用它並返回錯誤。

錯誤代碼:

Enter Anime:One Piece
Search All - MyAnimeList.net
Traceback (most recent call last):
  File "C:\Users\amete\Documents\Python\Code\Web test.py", line 29, in <module>
    link = driver.find_element_by_xpath("/html/body/div[2]/div[2]/div[3]/div[2]/div[2]/div[1]/div/article[1]/div[1]/div[2]/a[1]").click()
  File "C:\Users\amete\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webelement.py", line 80, in click
    self._execute(Command.CLICK_ELEMENT)
  File "C:\Users\amete\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "C:\Users\amete\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\amete\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <a href="https://myanimelist.net/anime/21/One_Piece" class="hoverinfo_trigger fw-b fl-l" id="#revAreaAnimeHover21" rel="#revInfo21" style="position: relative;">...</a> is not clickable at point (103, 339). Other element would receive the click: <div height="576" class="qc-cmp-cleanslate css-1kaql54">...</div>
  (Session info: chrome=91.0.4472.114)

我的代碼:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

import time
Anime = input("Enter Anime:")

PATH = r"C:\Users\amete\Documents\chromedriver.exe"
driver = webdriver.Chrome(PATH)

driver.get("https://myanimelist.net/search/all?q=one%20piece&cat=all")
print(driver.title)

# Since Selenium does not want to allow me to use the main page to search
# I got a link that I already searched with and then cleared it.This then allowed me to type whatever I wanted.
search = driver.find_element_by_xpath('/html/body/div[2]/div[2]/div[3]/div[2]/div[1]/form/div/div[1]/input[1]')


# Clears the field
search.send_keys(Keys.CONTROL, 'a')
search.send_keys(Keys.DELETE)

# The field is now cleared and the program can type whatever it wants
search.send_keys(Anime)
search.send_keys(Keys.RETURN)

link = driver.find_element_by_xpath("/html/body/div[2]/div[2]/div[3]/div[2]/div[2]/div[1]/div/article[1]/div[1]/div[2]/a[1]").click()


time.sleep(5)

您需要在該行之前添加等待/延遲。
最簡單粗暴的方法是放置某種睡眠,例如time.sleep(3) ,但最佳實踐是使用顯式等待,如下所示:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 20)
import time
Anime = input("Enter Anime:")

PATH = r"C:\Users\amete\Documents\chromedriver.exe"
driver = webdriver.Chrome(PATH)

driver.get("https://myanimelist.net/search/all?q=one%20piece&cat=all")
print(driver.title)

# Since Selenium does not want to allow me to use the main page to search
# I got a link that I already searched with and then cleared it.This then allowed me to type whatever I wanted.
search = driver.find_element_by_xpath('/html/body/div[2]/div[2]/div[3]/div[2]/div[1]/form/div/div[1]/input[1]')


# Clears the field
search.send_keys(Keys.CONTROL, 'a')
search.send_keys(Keys.DELETE)

# The field is now cleared and the program can type whatever it wants
search.send_keys(Anime)
search.send_keys(Keys.RETURN)

wait.until(EC.visibility_of_element_located((By.XPATH, "/html/body/div[2]/div[2]/div[3]/div[2]/div[2]/div[1]/div/article[1]/div[1]/div[2]/a[1]"))).click()

time.sleep(5)

此外,您的定位器非常糟糕。 他們應該更短更聰明。

你需要:

1 等待該字段變為可見

2 制作一個穩定的定位器:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

import time
# Anime = input("Enter Anime:")

driver = webdriver.Chrome(executable_path='/snap/bin/chromium.chromedriver')

driver.get("https://myanimelist.net/search/all?q=one%20piece&cat=all")
print(driver.title)

wait = WebDriverWait(driver, 20)
#  Accepting cookies
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#gdpr-modal-bottom button'))).click()
#  waiting for Search field
search = driver.find_element_by_xpath('//input[@name="q"]')
wait.until(EC.element_to_be_clickable((By.XPATH, '//input[@name="q"]')))

# Clears the field
search.send_keys(Keys.CONTROL, 'a')
search.send_keys(Keys.DELETE)

# The field is now cleared and the program can type whatever it wants
search.send_keys("anime")
search.send_keys(Keys.RETURN)
wait.until(EC.element_to_be_clickable((By.XPATH, '//h2[@id="anime"]//ancestor::div[@class="content-left"]//article[1]/div[contains(@class, "list")][1]/div[contains(@class, "information")]/a[1]')))
link = driver.find_element_by_xpath('//h2[@id="anime"]//ancestor::div[@class="content-left"]//article[1]/div[contains(@class, "list")][1]/div[contains(@class, "information")]/a[1]').click()


time.sleep(5)

該代碼在執行搜索后單擊第一個元素。 如果需要點擊其他元素,將XPath的部分改為: div[contains(@class, 'list')][2] , div[contains(@class, 'list')][3]等等. 您可以嘗試縮短此 XPath(可能是可能的)或找到另一個。

我建議看看 css 選擇器。 為您的案例找到它可能會更容易。 請注意,有一個 cookie 提示,在您的情況下不需要單擊,但如果您嘗試從頁面底部獲取元素,則可能需要單擊。

更新

我更新了代碼以包括單擊“接受 cookie”按鈕。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM