Nimrod
Nimrod

Reputation: 1

Selenium/Python - By.CSS_SELECTOR returns "An invalid or illegal selector was specified"

Hi y'all I been trying to learn Selenium with python by following this beginner course:https://www.youtube.com/watch?v=j7VZsCCnptM&ab_channel=freeCodeCamp.org

Because it is several years old some of the syntax has changed and the webpage they use for the tutorial has changed as well but so far I was still able to get it working and understand what I was doing wrong or when something had changed and I needed to look for new documentation.

But I finally hit a wall here. The task was for the program to select two date inside a calendar and the html for that section doesn't seem to have changed a lot from 2021 but I can't get it to work (Last def at the end of main)

main

import booking.constants as cons
import time
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

# IGNORE from selenium.webdriver.chrome.options import Options


class Booking(webdriver.Chrome):
    def __init__(self, driver_path=r"C:\SeleniumDrivers", teardown=False):
        self.driver_path = driver_path
        self.teardown = teardown
        os.environ['PATH'] += self.driver_path
        super(Booking, self).__init__()
        self.implicitly_wait(15)
        self.maximize_window()

        # ↑ Chrome setup

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.teardown:
            self.quit()
        # ↑ quits browser after running

    def land_first_page(self):
        self.get(cons.BASE_URL)
        # ↑ define action: redirect to BASE_URL

    def change_currency(self, currency=None):
        currency_element = self.find_element(By.CSS_SELECTOR, 'button[data-testid="header-currency-picker-trigger"]')
        # ↑ Finds the currency selector button
        currency_element.click()

        sltd_currency_element = self.find_elements(By.CSS_SELECTOR, 'button[data-testid="selection-item"]')
        # ↑ Makes a list of all buttons with data-testid="selection-item" (all currencies)
        for sltd_currency in sltd_currency_element:
            # ↓ Checks which item in the above list contains a partial pass with currency
            if currency in sltd_currency.text:
                sltd_currency.click()
                time.sleep(2)
                break  # DON'T FORGET TO BREAK THE MF 'FOR'

    def close_ini_popup(self):
        ini_popup_element = self.find_element(By.CSS_SELECTOR, 'button[aria-label="Dismiss sign-in info."]')
        ini_popup_element.click()

    # ↑ Closes the initial popup asking you to login

    def select_place_to_go(self, place_to_go=None):
        search_field = self.find_element(By.CLASS_NAME, 'eb46370fe1')
        search_field.clear()
        search_field.send_keys(place_to_go)
        search_result = self.find_element(By.ID, 'autocomplete-result-0')
        search_result.click()
        time.sleep(5)

    # ↑ Finds the destination field, clears it, fills it and selects the first result

    def select_dates(self, ci_date, co_date):
        check_in_element = self.find_element(By.CSS_SELECTOR, f'data-date="{ci_date}')
        check_in_element.click()

        check_out_element = self.find_element(By.CSS_SELECTOR, f'data-date="{co_date}')
        check_out_element.click()
    # ↑ Selects check in/out dates - YYYY/MM/DD

constant

BASE_URL = "https://www.booking.com/"

deploy

from booking.booking import Booking

with Booking() as bot:
    bot.land_first_page()
    bot.close_ini_popup()
    #bot.change_currency(currency='AUD')
    bot.select_place_to_go('Buenos Aires')
    bot.select_dates(ci_date='2024-05-19', co_date='2024-06-24')

while(True):
    pass  # lazy way to prevent browser from closing as soon as the program finishes

So far I tried looking for other CSS_Selectors for the dates, doing a for similar to the one I used for currency, using ec.presence_of_element_located() but no luck

Upvotes: 0

Views: 43

Answers (1)

JeffC
JeffC

Reputation: 25610

An example of an element you are looking for is

<span data-date="2024-05-01" ...>
    <span>1</span>
</span>

A valid CSS selector to find that SPAN would be

[data-date='2024-05-01']

but your code is producing

data-date="2024-05-01"

which is missing the brackets, []s.

You can update your code to the below to fix it

def select_dates(self, ci_date, co_date):
    self.find_element(By.CSS_SELECTOR, f'[data-date="{ci_date}]').click()
    self.find_element(By.CSS_SELECTOR, f'[data-date="{co_date}]').click()

Upvotes: 0

Related Questions