im trying to click a button on a page after logging in the button is the following HTML
<div id="carrierDashboardControls">
<button class="yms-button-primary" ng-click="refresh()">
<t>Refresh</t>
</button>
<button class="yms-button-primary-alt ng-isolate-scope" ng-csv="fetchData()" lazy-load="true"
csv-header="getCsvHeader" filename="carrier-dashboard.csv" field-separator=",">CSV
</button>
</div>
there are 2 buttons in this and i want to click the one with class
"yms-button-primary-alt ng-isolate-scope"
however i get the follwing error
this button will download a CSV file when clicked but right now i get the error "selenium.common.exceptions.WebDriverException: Message: Failed to convert data to an object"
im currently using the below code, note the actual url's cannot be shared due to the nature of the business (i navigate to the url twice due to a redirection after login)
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import re
import pandas as pd
import os
url = "THE URL"
username = 'USERNAME'
password = 'PASSWORD'
driver = webdriver.Firefox(executable_path=r'MYPATH/geckodriver.exe')
driver.implicitly_wait(100)
driver.get(url)
user_field = driver.find_element_by_id("ap_email")
pass_field = driver.find_element_by_id("ap_password")
sign_in = driver.find_element_by_id("signInSubmit")
user_field.send_keys(username)
pass_field.send_keys(password)
sign_in.click()
driver.implicitly_wait(100)
driver.get(url)
CSV_BUTTON = driver.find_element_by_class_name("yms-button-primary-alt ng-isolate-scope")
CSV_BUTTON.click()
as an added note i would like to manipulate the file that is downloaded afterwards as i would like to have it auto renamed with current date and time if this is possible ?
FULL STACKTRACE BELOW
Traceback (most recent call last):
File "C:/Users/USER/PycharmProjects/YMS scrape/venv/YMS Sel#.py", line 26, in <module>
CSV_BUTTON = driver.find_element_by_class_name("yms-button-primary-alt ng-isolate-scope")
File "C:\Users\USER\Anaconda3\envs\YMS scrape\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 564, in find_element_by_class_name
return self.find_element(by=By.CLASS_NAME, value=name)
File "C:\Users\USER\Anaconda3\envs\YMS scrape\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
'value': value})['value']
File "C:\Users\USER\Anaconda3\envs\YMS scrape\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\USER\Anaconda3\envs\YMS scrape\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Failed to convert data to an object
The desired element is an dynamic element which becomes visible through lazy-loading, so to click() on the element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.yms-button-primary-alt.ng-isolate-scope[csv-header='getCsvHeader'][ng-csv^='fetchData']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='yms-button-primary-alt ng-isolate-scope' and #csv-header='getCsvHeader'][contains(., 'CSV')]"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Related
I am trying to automate the login of a bunch of users to the fitbit site to download their data using the python's module selenium. Unfortunately I do not fully understand by looking at the source html code of the page, how to select the right elements.
My code looking something like this:
driver = webdriver.Firefox()
driver.get("https://accounts.fitbit.com/login")
driver.find_element_by_id("email").send_keys('name.surname#gmail.com')
driver.find_element_by_id("pass").send_keys("myfakepass")
driver.find_element_by_id("loginbutton").click()
But I do not know how to extract the element since driver.find_element_by_id("email") returns the error:
>>> driver.find_element_by_id("email")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 360, in find_element_by_id
return self.find_element(by=By.ID, value=id_)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="email"]
This makes totally sense to me since if I check the source page of https://accounts.fitbit.com/login I cannot detect any field called "email". But, probably due to my lack of experience, I cannot detect in the html source any of the elements that I need for the login.
Anyone could help me?
Thanks
Your locator seems wrong. Try with below xpath.
Induce WebDriverWait() and wait for element_to_be_clickable()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[#type='email']"))).send_keys('name.surname#gmail.com')
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[#type='password']"))).send_keys("myfakepass")
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[text()='Login']"))).click()
You need to import below libraries.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
There is a code that works.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
driver = webdriver.Chrome('your path')
url = "https://accounts.fitbit.com/login"
driver.get(url)
time.sleep(2)
email = driver.find_element_by_id("ember660")
email.send_keys("Edward#elric.com")
password = driver.find_element_by_id("ember661")
password.send_keys("Password")
login_button = driver.find_element_by_id("ember701").click()
Your program didn't work because of the id which are wrong
I came up with a simple code that works.
It has been very useful to use the "Inspect" command integrated in chrome for finding the id or the xpath relative to each field. Also the package time was needed to avoid errors.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
driver = webdriver.Chrome('path to chromedriver')
url = "https://accounts.fitbit.com/login"
driver.get(url)
time.sleep(2)
email = driver.find_element_by_id("ember659")
email.send_keys("mail#gmail.com")
password = driver.find_element_by_id("ember660")
password.send_keys('actualpassword')
driver.find_element_by_xpath('//*[#id="loginForm"]/div[4]/div').click()
I am essentially scraping chegg and I need help in trying to identify the css id= "emailForSignIn"
I am trying to find a way to detect where the text bar for the login section is for the chegg login page
Below is the function implemented:
def signin(): # Only use this function if you are using new instances of your browser each time
print('>>signing in!')
browser.get('https://www.chegg.com/auth?action=login&redirect=https%3A%2F%2Fwww.chegg.com%2F')
handle_captcha()
time.sleep(2)
email_elem = browser.find_element_by_id('emailForSignIn')
for character in 'alondra_calderon#ymail.com':
email_elem.send_keys(character)
time.sleep(0.1)
time.sleep(2)
password_elem = browser.find_element_by_id('passwordForSignIn')
for character in 'Blueyes97':
password_elem.send_keys(character)
time.sleep(0.1)
time.sleep(2)
browser.find_element_by_name('login').click()
try:
if WebDriverWait(browser, 5).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[1]/div[3]/div[2]/div[2]/div/div[3]/div/oc-component/div/div/div/div[2]/div[1]/div[1]/div/form/div/div/div/div/div[3]/span"))):
print('redirecting back to login')
browser.get('https://www.chegg.com/auth?action=login')
handle_captcha()
signin()
handle_captcha()
except TimeoutException:
pass
if browser.find_element_by_tag_name('h1').text == 'Oops, we\'re sorry!':
return [0]
handle_captcha()
Below is the error:
PS C:\Users\Dami\Desktop\chegg_discord_bot-master> & 'C:\Program Files (x86)\Python38-32\python.exe' 'c:\Users\Dami\.vscode\extensions\ms-python.python-2020.8.101144\pythonFiles\lib\python\debugpy\launcher' '58627' '--' 'c:\Users\Dami\Desktop\cheggDiscordBot.py'
DevTools listening on ws://127.0.0.1:58638/devtools/browser/837850c8-796e-44be-950f-49f667f48f0a
>>signing in!
Traceback (most recent call last):
File "c:\Users\Dami\Desktop\cheggDiscordBot.py", line 288, in <module>
signin()
File "c:\Users\Dami\Desktop\cheggDiscordBot.py", line 257, in signin
email_elem = browser.find_element_by_id('emailForSignIn')
File "C:\Users\Dami\AppData\Roaming\Python\Python38\site-packages\selenium\webdriver\remote\webdriver.py",
line 360, in find_element_by_id
return self.find_element(by=By.ID, value=id_)
File "C:\Users\Dami\AppData\Roaming\Python\Python38\site-packages\selenium\webdriver\remote\webdriver.py",
line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "C:\Users\Dami\AppData\Roaming\Python\Python38\site-packages\selenium\webdriver\remote\webdriver.py",
line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\Dami\AppData\Roaming\Python\Python38\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="emailForSignIn"]"}
(Session info: headless chrome=84.0.4147.125)
To send a character sequence to the Email and Password field you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get('https://www.chegg.com/auth?action=login&redirect=https%3A%2F%2Fwww.chegg.com%2F')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#emailForSignIn"))).send_keys("alondra_calderon#ymail.com")
driver.find_element_by_css_selector("input#passwordForSignIn").send_keys("passwordForSignIn")
Using XPATH:
driver.get('https://www.chegg.com/auth?action=login&redirect=https%3A%2F%2Fwww.chegg.com%2F')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#id='emailForSignIn']"))).send_keys("alondra_calderon#ymail.com")
driver.find_element_by_xpath("//input[#id='passwordForSignIn']").send_keys("passwordForSignIn")
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Browser Snapshot:
Seems synchronization issue as below error indicates-
Unable to locate element: {"method":"css
selector","selector":"[id="emailForSignIn"]"}
Introduce Explicit wait in your script and change your code as given below:
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "emailForSignIn"))).send_keys("alondra_calderon#ymail.com")
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "passwordForSignIn"))).send_keys("Blueyes97")
driver.find_element_by_name('login').click()
Note: No need to loop through the email and password Selenium automatically enters the text in same way
Import following packages for that:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
enter image description hereMy code is basically logging into a website (https://user.sensogram.com/signin) and download the CSV file by clicking on a button (Download CSV). However I am getting an errors that says:
File "c:\Users\USERPC\Desktop\python\sesno_login.py", line 57, in <module>
csv_file_button.click()
File "C:\Users\USERPC\AppData\Local\Programs\Python\Python36-32\lib\site-
packages\selenium\webdriver\remote\webelement.py", line 80, in click
self._execute(Command.CLICK_ELEMENT)
File "C:\Users\USERPC\AppData\Local\Programs\Python\Python36-32\lib\site-
packages\selenium\webdriver\remote\webelement.py", line 628, in _execute
return self._parent.execute(command, params)
File "C:\Users\USERPC\AppData\Local\Programs\Python\Python36-32\lib\site-
packages\selenium\webdriver\remote\webdriver.py", line 312, in execute
self.error_handler.check_response(response)
File "C:\Users\USERPC\AppData\Local\Programs\Python\Python36-32\lib\site-
packages\selenium\webdriver\remote\errorhandler.py", line 242, in
check_response raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error:
Element <tspan>...</tspan> is not clickable at point (1232, 413). Other
element would receive the click: <div class="page-loading ng-scope" ng-
if="showPreloader" style="">...</div>
It's like that the code can't locate the click button on the page for some reason. This is what I wrote so far:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.common.exceptions import NoSuchElementException
import time
chromedriver = "/webdrivers/chromedriver"
driver = webdriver.Chrome(chromedriver)
driver.maximize_window()
driver.get('https://user.sensogram.com/signin') #driver.get(url)-- We get
url by using driver which we initialy load.
print ("Opened sensogram")
time.sleep(5) #Just wait for sometime.
email = driver.find_element_by_xpath("//input[#name='usernameSignIn']")
#Find email textaera.
email.send_keys('****') #Send email to this text area.
password = driver.find_element_by_xpath("//input[#name='passwordSignIn']")
#Find password textarea.
password.send_keys('*******') #send password to the password field.
button = driver.find_element_by_xpath("//button[#ng-
click='submitted=true']") #Find login button.
button.click() #Click on login button.
driver.implicitly_wait(10)
csv_file_button = driver.find_element_by_xpath("//*[name()='tspan' and
.='Download CSV']")
csv_file_button.click()
print(csv_file_button)
can someone figure out why i Keep getting this type of error? plus this is the webpage HTML of the csv file:
<g class="highcharts-button highcharts-contextbutton highcharts-button-
normal" style="cursor:pointer;vertical-align:center;font-size:12;font-
weight:500;" stroke-linecap="round" transform="translate(379,8)">
<title>Chart context menu</title><rect fill="rgba(0, 0, 0, 0.7)" class="
highcharts- button-box" x="0.5" y="0.5" width="100" height="32" rx="2"
ry="2" stroke="none" stroke-width="1"></rect><text x="7" style="font-
weight:normal;color:#fff;fill:#fff;" y="19"><tspan>Download CSV</tspan>
</text></g>
Sometimes selenium webdriver could not find elements, so better use javascript executor to click on desired button
Example:
js = (JavascriptExecutor) driver;
js.executeScript("$('#downloadcsv').click()");
I have a simple task that I want to automate. I want to open a URL, click a button which takes me to the next page, fills in a search term, clicks the "search" button and prints out the url and source code of the results page. I have written the following.
from selenium import webdriver
import time
driver = webdriver.PhantomJS()
driver.set_window_size(1120, 550)
#open URL
driver.get("https://www.searchiqs.com/nybro/")
time.sleep(5)
#click Log In as Guest button
driver.find_element_by_id('btnGuestLogin').click()
time.sleep(5)
#insert search term into Party 1 form field and then search
driver.find_element_by_id('ContentPlaceholder1_txtName').send_keys("Moses")
driver.find_element_by_id('ContentPlaceholder1_cmdSearch').click()
time.sleep(10)
#print and source code
print driver.current_url
print driver.page_source
driver.quit()
I am not sure where I am going wrong but I have followed a number of tutorials on how to click buttons and fill forms. I get this error instead.
Traceback (most recent call last):
File "phant.py", line 12, in <module>
driver.find_element_by_id('btnGuestLogin').click()
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 269, in find_element_by_id
return self.find_element(by=By.ID, value=id_)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 752, in find_element
'value': value})['value']
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 236, in execute
self.error_handler.check_response(response)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 192, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: {"errorMessage":"Unable to find element with id 'btnGuestLogin'","request":{"headers":{"Accept":"application/json","
Accept-Encoding":"identity","Connection":"close","Content-Length":"94","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:35670","User-Agent":"Python-urllib/2.7"
},"httpVersion":"1.1","method":"POST","post":"{\"using\": \"id\", \"sessionId\": \"d38e5fa0-5349-11e6-b0c2-758ad3d2c65e\", \"value\": \"btnGuestLogin\"}","url":"/element","urlP
arsed":{"anchor":"","query":"","file":"element","directory":"/","path":"/element","relative":"/element","port":"","host":"","password":"","user":"","userInfo":"","authority":""
,"protocol":"","source":"/element","queryKey":{},"chunks":["element"]},"urlOriginal":"/session/d38e5fa0-5349-11e6-b0c2-758ad3d2c65e/element"}}
Screenshot: available via screen
The error seems to suggest that the element with that id does not exist yet it does.
--- EDIT: Changed code to use WebDriverWait ---
I have changed some things around to implement WebDriverWait
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
import time
driver = webdriver.PhantomJS()
driver.set_window_size(1120, 550)
#open URL
driver.get("https://www.searchiqs.com/nybro/")
#click Log In as Guest button
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "btnGuestLogin"))
)
element.click()
#wait for new page to load, fill in form and hit search
element2 = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "ContentPlaceholder1_cmdSearch"))
)
#insert search term into Party 1 form field and then search
driver.find_element_by_id('ContentPlaceholder1_txtName').send_keys("Moses")
element2.click()
driver.implicitly_wait(10)
#print and source code
print driver.current_url
print driver.page_source
driver.quit()
It still raises this error
Traceback (most recent call last):
File "phant.py", line 14, in <module>
EC.presence_of_element_located((By.ID, "btnGuestLogin"))
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/support/wait.py", line 80, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
Screenshot: available via screen
The WebDriverWait approach actually works for me as is:
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
driver = webdriver.PhantomJS()
driver.set_window_size(1120, 550)
driver.get("https://www.searchiqs.com/nybro/")
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "btnGuestLogin"))
)
element.click()
No errors. PhantomJS version 2.1.1, Selenium 2.53.6, Python 2.7.
The issue might be related to SSL and PhantomJS, either work through http:
driver.get("http://www.searchiqs.com/nybro/")
Or, try ignoring SSL errors:
driver = webdriver.PhantomJS(service_args=['--ignore-ssl-errors=true', '--ssl-protocol=any'])
I need your help. I'm trying to scrape some data from tripadvisor using Selenium in Python 2.7. However, I'm getting stuck at one point.
After browsing to the correct page, I'm trying to filter the hotels on certain prices. To do this, you do a mouse over or click on 'price' and then select the appropiate value like (€3 - € 13).
After clicking on price and then the value. I'm getting the error that the element is not visible or unable to locate, while it is clearly visible.
code
from urllib import urlopen
import time
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
city = 'nha thrang'
url = 'http://www.tripadvisor.nl/Hotels'
driver = webdriver.Firefox()
# open browser
driver.get(url)
time.sleep(5)
# insert city & dates
driver.find_element_by_id('searchbox').send_keys(city)
driver.find_element_by_id('date_picker_in_188616').click()
driver.find_elements_by_class_name('day')[15].click()
driver.find_element_by_id('date_picker_out_188616').click()
driver.find_elements_by_class_name('day')[16].click()
time.sleep(5)
# click search
driver.find_element_by_id('SUBMIT_HOTELS').click()
# close popup
time.sleep(5)
try:
driver.switch_to.window(driver.window_handles[1])
driver.close()
driver.switch_to.window(driver.window_handles[0])
except:
''
# click on 'price'. Works!
driver.find_element_by_xpath('//div[starts-with(#class, "JFY_hotel_filter_icon enabled price sprite-price")]').click()
# click on particular price. doesn't work.
driver.find_element_by_xpath('//div[starts-with(#class, "jfy_tag_style jfy_filter_p_4 jfy_cloud")]').click()
Error
Traceback (most recent call last):
File "<pyshell#30>", line 1, in <module>
driver.find_element_by_xpath('//div[starts-with(#class, "jfy_tag_style jfy_filter_p_4 jfy_cloud")]').click()
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 230, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 662, in find_element
{'using': by, 'value': value})['value']
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 173, in execute
self.error_handler.check_response(response)
File "C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 166, in check_response
raise exception_class(message, screen, stacktrace)
NoSuchElementException: Message: Unable to locate element: {"method":"xpath","selector":"//div[starts-with(#class, \"jfy_tag_style jfy_filter_p_4 jfy_cloud\")]"}
Stacktrace:
at FirefoxDriver.prototype.findElementInternal_ (file:///c:/users/j6057~1.kro/appdata/local/temp/tmpdgovsc/extensions/fxdriver#googlecode.com/components/driver-component.js:9641:26)
at FirefoxDriver.prototype.findElement (file:///c:/users/j6057~1.kro/appdata/local/temp/tmpdgovsc/extensions/fxdriver#googlecode.com/components/driver-component.js:9650:3)
at DelayedCommand.prototype.executeInternal_/h (file:///c:/users/j6057~1.kro/appdata/local/temp/tmpdgovsc/extensions/fxdriver#googlecode.com/components/command-processor.js:11635:16)
at DelayedCommand.prototype.executeInternal_ (file:///c:/users/j6057~1.kro/appdata/local/temp/tmpdgovsc/extensions/fxdriver#googlecode.com/components/command-processor.js:11640:7)
at DelayedCommand.prototype.execute/< (file:///c:/users/j6057~1.kro/appdata/local/temp/tmpdgovsc/extensions/fxdriver#googlecode.com/components/command-processor.js:11582:5)
You need to apply multiple changes to make it work:
use Chrome() driver to avoid opening multiple windows after clicking "Search"
don't use hardcoded time.sleep() intervals - use "Explicit Waits"
date picker element ids are changing, you need to use starts-with() to find them
use ActionChains() to hover the price element and wait for range to become visible
Working code (selecting "USD 25 - 50" range):
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
city = 'nha thrang'
url = 'http://www.tripadvisor.nl/Hotels'
driver = webdriver.Chrome()
driver.get(url)
# insert city & dates
searchbox = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'searchbox')))
searchbox.send_keys(city)
driver.find_element_by_xpath('//span[starts-with(#id, "date_picker_in_")]').click()
driver.find_elements_by_class_name('day')[15].click()
driver.find_element_by_xpath('//span[starts-with(#id, "date_picker_out_")]').click()
driver.find_elements_by_class_name('day')[16].click()
# click search
driver.find_element_by_id('SUBMIT_HOTELS').click()
# select price range
price = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//div[starts-with(#class, "JFY_hotel_filter_icon enabled price sprite-price")]')))
ActionChains(driver).move_to_element(price).perform()
price_range = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '(//div[contains(#class, "jfy_filter_bar_price")]//div[#value="p 8"])[last()]')))
price_range.click()
Results into:
i got the same Traceback , try add this before find your elements:
driver.switch_to_window(driver.window_handles[1])#locate the first new page (handles)
anyway it works for me