pythonselenium-webdriverweb-scrapingselenium-chromedriver

Can't close cookie pop up on website with selenium webdriver


I am trying to use selenium to click the Accept all or Reject all button on a cookie pop up for the the website autotrader.co.uk, but I cannot get it to make the pop up disappear for some reason.

This is the pop up:

enter image description here

and here is the html:

<button title="Reject All" aria-label="Reject All" class="message-component message-button no-children focusable sp_choice_type_13" style="opacity: 1; padding: 10px 5px; margin: 10px 5px; border-width: 2px; border-color: rgb(5, 52, 255); border-radius: 5px; border-style: solid; font-size: 14px; font-weight: 400; color: rgb(255, 255, 255); font-family: arial, helvetica, sans-serif; width: calc(35% - 20px); background: rgb(5, 52, 255);">Reject All</button>

enter image description here

The code I have tried is the following:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
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

path_to_driver = r"C:\path_to_project\chromedriver.exe"
service = Service(executable_path=path_to_driver)

driver = webdriver.Chrome(service=service)
driver.get("https://www.autotrader.co.uk")
time.sleep(5)
WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.CLASS_NAME, 'message-component message-button no-children focusable sp_choice_type_13'))).click()

time.sleep(10)
driver.quit()

Can anyone help here?


Solution

  • As you can see, the pop-up window is embedded within an <iframe>Selenium must first switch the driver's context to that iframe before attempting to locate or interact with any elements contained within it.

    wait for the desired iframe element to be available to switch to it:

    iframe = wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, 'iframe[id^="sp_message_iframe_"]')))
    

    Note: Since the id attribute of the iframe appears to be dynamically generated, it is recommended to locate the iframe using a partial match strategy, such as CSS selector or XPath with the contains() function or partial match strategy ( https://stackoverflow.com/a/56844649/11179336)

    This is how you can do:

    import time
    from selenium.webdriver import Chrome, ChromeOptions
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    chrome_options = ChromeOptions()
    chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])
    driver = Chrome(options=chrome_options)
    
    driver.get("https://www.autotrader.co.uk")
    wait = WebDriverWait(driver, 10)
    
    # wait for the target iframe to get loaded in order to switch to it
    wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, 'iframe[id^="sp_message_iframe_"]')))
    
    # click to 'Reject All'
    wait.until(EC.element_to_be_clickable((By.XPATH, '//button[@title="Reject All"]'))).click()
    
    # Switch back to the main page content
    driver.switch_to.default_content()
    
    # Now you can continue interacting with the main page here
    
    time.sleep(5)