I am facing interesting issue with my **Web Scraping** use case. I need to get newest **Google Maps reviews**.
I want to sort reviews by latest date. And all tutorials I am watching is in English, but in my native language the UI is different than in those tutorials.
I am able to click on the button using **Selenium** and button's **XPATH**, but I don't know how to change the sorting options from the visible drop menu.
# Click the sort button
driver.find_element_by_xpath('//*[@id="pane"]/div/div[1]/div/div/div[2]/div[8]/button').click()
select_by_visible_text() and select_by_value() doesn't work for me as I cannot select the button and doesn't work on div.
URL I am using : Link
To see my UI change to LITHUANIAN language.
CodePudding user response:
First of all you have to learn how to create correct XPath locators.
Long XPath expressions are too fragile.
The "Sort Reviews" button locator instead of
//*[@id="pane"]/div/div[1]/div/div/div[2]/div[8]/button can be
//button[@aria-label='Sort reviews'] or
//button[@data-value='Sort']
After clicking this button, to sort reviews by latest date you can click this element: //li[@data-index='1']
So basically this will work:
driver.find_element_by_xpath("//li[@data-index='1']").click()
But since you need to wait for dialog to open after clicking the Sort button you need to utilize Expected Condition wait, as following:
wait = WebDriverWait(driver, 20)
wait.until(EC.visibility_of_element_located((By.XPATH, "//li[@data-index='1']"))).click()
You will need the following imports for this:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
CodePudding user response:
This code should work.
I added a webdriverwait after clicking on the 'Sort' button to wait until the all the options in the dropdown are visible, then clicked on 'Highest rating'.
//li[@role='menuitemradio'])[3] refers to the 3rd element in the dropdown which is the 'Higest rating'. I tried using the text to be specific and not count on element index, but somehow it is not working. But the below code does sort the reviews.
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
from webdriver_manager.chrome import ChromeDriverManager
import time
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.maximize_window()
driver.get("https://www.google.com/maps/place/Senukai/@54.6832836,25.183965,12z/data=!4m11!1m2!2m1!1svilnius senukai!3m7!1s0x46dd94055529fabf:0xb1132b0ad981d43b!8m2!3d54.7098368!4d25.2999662!9m1!1b1!15sCg92aWxuaXVzIHNlbnVrYWkiA4gBAVoRIg92aWxuaXVzIHNlbnVrYWmSARhidWlsZGluZ19tYXRlcmlhbHNfc3RvcmU")
print(driver.title)
time.sleep(5)
driver.find_element(By.XPATH, "//button[@data-value='Sort']").click()
WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.XPATH, "//li[@role='menuitemradio']")))
driver.find_element(By.XPATH, "(//li[@role='menuitemradio'])[3]").click()
time.sleep(2)
driver.quit()
P.S I used time.sleep occasionally to make a quick code, but it would be a good practice to use WebdriverWait in lieu of time.sleep

