I'm using Python with Selenium to create a scraper that gets the prices of Disney World tickets from the official website for each ticket with different numbers of days.
The script works fine up until the web driver attempts to click on the arrow button to change the current month. In the below code, this occurs where I use ActionChains to move to the element nextArrow and click on it. I am getting this error:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable: [object HTMLElement] has no size and location
I have tried using the Selenium click action, ActionChains, and JavaScript to click on the element, but nothing has worked so far. It appears that the nextArrow WebElement has aria-hidden=true set in the HTML of the site.
Here are the imports and setup code:
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()
Here is the code that runs the scraper:
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
Any advice on how to handle this issue? Thanks in advance!