Changing pickup and dropoff dates in turo using playwright

Question:

Hi I’m trying to scrape some data from this site https://turo.com/us/en/car-rental/united-states/austin-tx/tesla/model-s/1733237?endDate=11%2F09%2F2022&endTime=11%3A00&startDate=11%2F05%2F2022&startTime=11%3A00 using playwright but I’m struggling with changing the date and time. At first I tried to make my bot click on the date and time boxes but I kept running into issues so I decided to change my approach.

Now I’m trying to change the URL so that the bot directly goes to the dates that I want instead of going to the default dates but I haven’t found a way for it to work since it keeps redirecting me to the default page.

example:

https://turo.com/us/en/car-rental/united-states/austin-tx/tesla/model-s/1733237?endDate=11%2F09%2F2022&endTime=11%3A00&startDate=11%2F05%2F2022&startTime=11%3A00

This link takes you to start date 11/05/2022 and end date 11/09/2022 but want to change it so that by changing endDate=11%2F09%2F2022 it takes me to a date I decide instead of redirecting me back to the default dates.

Is there another way of changing the date that is easier?

with sync_playwright() as p:


    browser = p.chromium.launch(headless=False)
    context = browser.new_context(user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36')
    page = browser.new_page()
    page.goto("https://turo.com/us/en/car-rental/united-states/austin-tx/tesla/model-s/1733237?endDate=11%2F10%2F2022&endTime=11%3A00&startDate=11%2F05%2F2022&startTime=11%3A00")


    time.sleep(5)
    
    html = page.inner_html('#__next')
    soup = BeautifulSoup(html, 'html.parser')
Asked By: Guri 100

||

Answers:

It is not possible to do it with the URL as I can see

Anyways, I prepared an script for making what you wanted. I used an auxiliar function that you can use. I hope it works for you.

import time
from playwright.sync_api import Playwright, sync_playwright, expect

#This function wait for an element, if the element is not present it return false instead of throwing an exception and stopping the script. If element is not present after the timeout, it return false and we can use that false for our desired flow
def wait_for_selector_with_no_exception(page, selector, timeout):
    try:
        page.wait_for_selector(selector, timeout=timeout)
        return True
    except:
        return False

with sync_playwright() as p:
    #We define the browser, the context and the page
    browser = p.chromium.launch(headless=False)
    context = browser.new_context(
        user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36')
    page = browser.new_page()

    #We navigate to URL of the car we want (In this case the Tesla from your example)
    url_for_car = "https://turo.com/us/en/car-rental/united-states/austin-tx/tesla/model-s/1733237"
    page.goto(url_for_car)

    #We do click into start date dropdown element
    page.locator("#reservationDates-dateRangePicker").click()

    #Here we define the selector for the start date we want (You can replace it with your desired date, of course)
    selector_for_start_date="//td[contains(@aria-label,'December 29, 2022')]"

    #We use our auxiliar function to see if the start date is within the DOM, if not we click on arrow for moving to next month
    while not wait_for_selector_with_no_exception(page=page, selector=selector_for_start_date, timeout=2000):
        page.locator(".DayPickerNavigationNext_icon").click()

    #Once desired start date is within the DOM we click on it
    page.locator(selector_for_start_date).click()

    #This selector is the second datepicker element once is open
    selector_when_date_end_is_open = '//div[@class="DateInput_displayText DateInput_displayText__focused DateInput_displayText__has-input"]/..//input[@id="reservationDates-dateRangePicker-endDate"]'

    #We wait till the second datepicker is already open
    page.wait_for_selector(selector_when_date_end_is_open)

    #Here we define the selector for the end date we want (Also you can replace it with your desired end date)
    selector_for_end_date="//td[contains(@aria-label,'March 23, 2023')]"

    #Same we did with start date but with end date, we wait for our end date element, if is not present we click on next arrow
    while not wait_for_selector_with_no_exception(page=page, selector=selector_for_end_date, timeout=2000):
        page.locator(".DayPickerNavigationNext_icon").click()

    #Once our end date is present we click on it
    page.locator(selector_for_end_date).click()

    #This sleep you can remove it, is only for you to see that it worked as expected
    time.sleep(10)

    #We close the context and the browser
    context.close()
    browser.close()

As you can see, I used xpath for my selectors because it is what I have under control, if you find a way of doing it with CSS go ahead.

Answered By: Jaky Ruby
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.