pythonselenium-webdriverseleniumbase

Exit Cookies pop-up on UPS website using Python with Selenium and SeleniumBase


This is the code i'm using, I pass a fake tracking number for now, I close the chat window, and then attempt to close the cookies window. But for some reason I just cannot click the X button, any help would be greatly appreciated.

Everything here works besides the last line.. You should be able to copy/paste into a .py file and test for yourself, given you have the correct packages installed.

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import NoSuchElementException
import time
import os
import pandas as pd
import pyautogui
import undetected_chromedriver as uc
from seleniumbase import Driver
from selenium.webdriver.common.action_chains import ActionChains

# Add the driver options
driver = Driver(uc=True)

with driver:
    # Go to the target website
    driver.get("https://google.com")
    driver.maximize_window()
#driver.set_window_size(1920, 820)
time.sleep(2)

driver.get("https://www.ups.com/track?track=yes&trackNums=1Z12345E1512345676&loc=en_US&requester=ST/")
time.sleep(3)
# Create another loop to run based on which element is found.

# Find UPS Element
U_Ele = driver.find_element(By.XPATH, "//span[contains(text(), 'UPS')]")
print(f"UPS Element found")

#Switch to UPS iframe
iframe = driver.find_element(By.XPATH, "//iframe[@id='inqChatStage']")
driver.switch_to.frame(iframe)
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="top-bar"]/div/div[1]/div[1]/topbar-element/div/div/div/div'))).click()
time.sleep(2)
driver.find_element(By.XPATH, '//button[@class="close_btn"]').click()

enter image description here


Solution

  • The problem is that you switched context into the IFRAME but never returned from that context. Selenium was looking for the cookie panel close button inside the IFRAME. To take the context back to the full page, you need to use driver.switch_to.default_content().


    Additional suggestions:

    1. Avoid time.sleep(). They make your script slower and aren't flexible like WebDriverWait.
    2. Use WebDriverWait consistently. You should use a wait on every element interaction/.find_element() call. If you are going to click on the element then use EC.element_to_be_clickable(). If you are going to interact with an element in other ways (get .text, etc., use EC.visibility_of_element_located(). Review the docs for more wait types and other info.
    3. You were navigating twice... first to google then to the UPS site. You only need to navigate once.
    4. Keep your imports clean. You had two different instances where you imported WebDriverWait and a bunch of other imports you aren't using. Keeping the imports list down to only what's necessary reduces code and confusion as you are coding.
    5. You should prefer By.ID() and By.CSS_SELECTOR() to XPaths. IDs are the simplest and least likely to change on the page. CSS selectors are faster and a simpler syntax than XPaths.

    Taking all this into account, I simplified your code down to the working code below,

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.wait import WebDriverWait
    
    url = 'https://www.ups.com/track?track=yes&trackNums=1Z12345E1512345676&loc=en_US&requester=ST/'
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get(url)
    
    wait = WebDriverWait(driver, 5)
    
    # switch to chat IFRAME and close chat
    wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, "inqChatStage")))
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div[aria-label='End Chat']"))).click()
    driver.switch_to.default_content()
    
    # close cookies panel
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.implicit_consent span.ups-icon-x"))).click()
    
    driver.quit()