【问题标题】:Python3 with Selenium ElementNotInteractable: Object has no size and locationPython with Selenium Element Not Interactable:对象没有大小和位置
【发布时间】:2021-08-16 16:55:02
【问题描述】:

我正在将 Python 与 Selenium 一起使用来创建一个刮板,它可以从 official website 获取不同天数的每张门票的迪士尼世界门票价格。

在网络驱动程序尝试单击箭头按钮更改当前月份之前,该脚本工作正常。在下面的代码中,这发生在我使用 ActionChains 移动到元素 nextArrow 并单击它的地方。我收到此错误:

selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable: [object HTMLElement] has no size and location

我曾尝试使用 Selenium 点击动作、ActionChains 和 JavaScript 来点击元素,但到目前为止没有任何效果。 nextArrow WebElement 似乎在网站的 HTML 中设置了 aria-hidden=true

这里是导入和设置代码:

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC

DRIVER_PATH = "/Volumes/WD Drive/Applications/Chromedriver/chromedriver"
driver = webdriver.Chrome(executable_path = DRIVER_PATH)
driver.maximize_window()

这是运行爬虫的代码:

driver.get("https://disneyworld.disney.go.com/admission/tickets/")

# Opens shadow roots and returns the new DOM root
def getShadowRoot(host):
    shadowRoot = driver.execute_script("return arguments[0].shadowRoot", host)
    return shadowRoot

# Select ticket and navigate to next screen
host1 = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.TAG_NAME, "tickets-spa")))
root1 = getShadowRoot(host1)

host2 = WebDriverWait(root1, 5).until(EC.presence_of_element_located((By.TAG_NAME, "tickets-listing-page")))
root2 = getShadowRoot(host2)

host3 = WebDriverWait(root2, 5).until(EC.presence_of_element_located((By.ID, "selectTicketType")))
root3 = getShadowRoot(host3)

host4 = WebDriverWait(root3, 5).until(EC.presence_of_element_located((By.TAG_NAME, "tickets-brick")))
root4 = getShadowRoot(host4)

selectButton = WebDriverWait(root4, 5).until(EC.presence_of_element_located((By.ID, "select")))
selectButton.click()

# Select the number of days and dates
host1 = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.TAG_NAME, "tickets-spa")))
root1 = getShadowRoot(host1)

host2 = WebDriverWait(root1, 5).until(EC.presence_of_element_located((By.TAG_NAME, "tickets-config-page")))
root2 = getShadowRoot(host2)

host3 = WebDriverWait(root2, 5).until(EC.presence_of_element_located((By.TAG_NAME, "tickets-num-days")))
root3 = getShadowRoot(host3)

numDaysContainer = WebDriverWait(root3, 5).until(EC.presence_of_element_located((By.ID, "days")))
numDaysButtons = numDaysContainer.find_elements_by_class_name("button-container")

# Loop through each ticket type by clicking on the number of days button
for button in numDaysButtons:
    button.click()
    productSelector = WebDriverWait(root2, 5).until(EC.presence_of_element_located((By.ID, "productSelector")))
    selectorRoot = getShadowRoot(productSelector)
    selectorRoot.find_element_by_id("theme-parks").click()
    
    time.sleep(5)
    
    calendarHost1 = WebDriverWait(root2, 5).until(EC.presence_of_element_located((By.ID, "lowestPriceModal")))
    calendarRoot1 = getShadowRoot(calendarHost1)

    calendarHost2 = WebDriverWait(calendarRoot1, 5).until(EC.presence_of_element_located((By.ID, "wdatCalendar")))
    calendarRoot2 = getShadowRoot(calendarHost2)

    nextArrowIcon1 = WebDriverWait(calendarRoot2, 5).until(EC.presence_of_element_located((By.ID, "nextArrow")))
    nextArrowShadow1 = getShadowRoot(nextArrowIcon1)

    nextArrowIcon2 = WebDriverWait(nextArrowShadow1, 5).until(EC.presence_of_element_located((By.TAG_NAME, "dprd-icon")))
    nextArrowShadow2 = getShadowRoot(nextArrowIcon2)

    nextArrow = WebDriverWait(nextArrowShadow2, 5).until(EC.presence_of_element_located((By.TAG_NAME, "dprd-html")))

    # Clicks on the calendar's arrow buttons to change the current month
    for i in range(12):
        action = ActionChains(driver)
        action.move_to_element(nextArrow).perform()
        time.sleep(3)
        action.click() # Exception thrown here

关于如何处理这个问题的任何建议?提前致谢!

【问题讨论】:

    标签: python selenium selenium-webdriver web-scraping


    【解决方案1】:

    即使没有调试您的代码,我也可以猜到,您应该将 presence_of_element_located 的预期条件更改为 visibility_of_element_located
    presence_of_element_located 条件在刚刚创建元素时满足,但仍未完全呈现。在这个早期阶段访问元素通常会导致您面对ElementNotInteractableException
    presence_of_element_located 应该主要用于不可见和不可点击的元素。

    【讨论】:

    • 这解决了问题!它开始定位元素,我只需要使用 JavaScript 来实际单击按钮,因为 ActionChains 不起作用。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    相关资源
    最近更新 更多