【问题标题】:Python Selenium element click interceptedPython Selenium 元素点击被拦截
【发布时间】:2021-09-04 04:59:16
【问题描述】:

我试图让 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)

【问题讨论】:

    标签: python selenium selenium-webdriver web-scraping xpath


    【解决方案1】:

    您需要在该行之前添加等待/延迟。
    最简单和最残酷的方法是在其中放置某种睡眠,例如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)
    

    另外,您的定位器非常糟糕。它们应该更短更聪明。

    【讨论】:

      【解决方案2】:

      你需要:

      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”按钮。

      【讨论】:

      • 那么这是否适用于其他标题而不是“动漫”?如果是这样,我将如何做到这一点,因为我尝试取消注释 Anime 变量并将其放入链接 = driver.find。例如,我想搜索 Erased 或任何其他动漫标题,而不是“动漫”
      • selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element &lt;a href="https://myanimelist.net/anime/35427/..." class="hoverinfo_trigger fw-b fl-l" id="#revAreaAnimeHover35427" rel="#revInfo35427" style="position: relative;"&gt;Animegataris&lt;/a&gt; is not clickable at point (114, 339). Other element would receive the click: &lt;div height="576" class="qc-cmp-cleanslate css-1kaql54"&gt;...&lt;/div&gt; (Session info: chrome=91.0.4472.114) 它发现我想要它点击但它没有点击它。我添加了wait.until
      • 你有意见不和吗?该代码第一次工作,但现在它一直告诉我错误
      • 检查更新的答案。它总是对我有用
      • 我发现了问题是网站上的 cookie 通知阻止了它。我需要找到一种方法来接受 cookie。你知道方法吗?感谢您的帮助
      猜你喜欢
      • 2020-01-04
      • 2021-10-08
      • 2020-02-23
      • 2019-12-29
      • 2019-11-08
      • 2022-01-05
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多