Selenium Python - cannot select options selection box - python

A website about stocks has a nice chart with several options for displaying the chart (see https://www.boerse.de/chart-tool/HeidelbergCement-Aktie/DE0006047004). I always need the chart for different stocks, but always with the same settings for the chart, so I would like to automate the selection of the settings for the chart. For example, I would always like to select the option "Barchart" (<option value = "Balken"> Bar-Chart </option>) in the select box for the chart type <select id = "types"). But I can't control the options in the chart. Possibly because it's a multilayered selection box.
In this respect, my (not working) code is:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import time
driver=webdriver.Chrome()
url ="https://www.boerse.de/chart-tool/HeidelbergCement-Aktie/DE0006047004"
driver.get(url)
time.sleep(10)
target = driver.find_element_by_class_name("box_full")
target.location_once_scrolled_into_view
driver.maximize_window()
select = Select(driver.find_element(By.ID,"types"))
select.select_by_value(“Balken”) # that doesn’t work
I get the following error message:
Traceback (most recent call last):
File "C:/Users/peter/Desktop/Python2020/Selenium/Selenium02.py", line 52, in <module>
select.select_by_value('Balken')
File "C:\Users\peter\AppData\Local\Programs\Python\Python38\lib\site-Charttyp <select id="types") packages\selenium\webdriver\support\select.py", line 82, in select_by_value
self._setSelected(opt)
File "C:\Users\peter\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\support\select.py", line 212, in _setSelected
option.click()
File "C:\Users\peter\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webelement.py", line 80, in click
self._execute(Command.CLICK_ELEMENT)
File "C:\Users\peter\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webelement.py", line 693, in _execute
return self._parent.execute(command, params)
File "C:\Users\peter\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 418, in execute
self.error_handler.check_response(response)
File "C:\Users\peter\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 243, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable: Element is not currently visible and may not be manipulated
(Session info: chrome=94.0.4606.81)

The "element not intractable" error usually means the element is not visible or there is some other element on top of it, therefore selenium can't interact with it.
Solution is check if the #types element is actually visible on the screen when you try to interact with it.
You might be able to change the select value through pure javascript too, using execute_script, but that might have the downside of not triggering events that would supposedly be triggered.

Related

Locating a website element using selenium webdriver for automation task

I am working on a project using selenium webdriver which requires me to locate an element and click on it. The program starts by entering a website , clicking the searchbar , typing in a preentered string and clicking enter , up to this point everything is successful. The next thing I want it to do is find the first result of the search and click on it. This part I am having trouble with. I have successfully located all elements up to this point but i cant locate this one as an error pops up. Here is my code:
from selenium import webdriver
import time
trackname = input("Track Name: ")
driver = webdriver.Chrome('D:\WebDrivers\chromedriver.exe')
driver.get('https://music.apple.com/us/artist/search/166949667')
time.sleep(2)
searchbox = driver.find_element_by_tag_name('input')
searchbox.send_keys(trackname)
from keyboard import press
press('enter')
time.sleep(2)
result = driver.find_element_by_id('search-list-lockup__description')
result.click()
I have tried locating the element other ways but it wont work , I am guessing that the issue is that after searching I have to tell it to search on that page but I am not sure. Here is the error:
Traceback (most recent call last):
File "D:\Python Projekti\iTunesDataFiller\iTunesDataFiller.py", line 18, in <module>
result = driver.find_element_by_id('search-list-lockup__description')
File "D:\Python App\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 360, in find_element_by_id
return self.find_element(by=By.ID, value=id_)
File "D:\Python App\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "D:\Python App\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "D:\Python App\lib\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="search-list-lockup__description"]"}
(Session info: chrome=89.0.4389.114)
Process finished with exit code 1
What do I do?
This could be due to the element you want to access not being available.
For example say you load the page, the element could not be visible to selenium. So basically you're trying to click on an invisible element.
I suggest using this template to make sure elements are loaded before accessing them.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
waitshort = WebDriverWait(driver,.5)
wait = WebDriverWait(driver, 20)
waitLonger = WebDriverWait(driver, 100)
visible = EC.visibility_of_element_located
driver = webdriver.Chrome(executable_path='path')
driver.get('link')
element_you_want_to_access = wait.until(visible((By.XPATH,'xpath')))

Click on specific button with selenium

Python, Selenium, XPath.
I want to open this page https://www.tesla.com/en_gb/models/design#battery and click the performance button programmatically with python.
Here is what I want to click on:
image showing what I want to click on
My problem is properly describing the button. Maybe I don't understand xpath properly or there's a better method to point to the desired element.
Here's what I tried
from selenium import webdriver
browser = webdriver.Chrome('../Downloads/chromedriver.exe')
browser.get('https://www.tesla.com/en_gb/models/design#battery')
A = browser.find_element_by_xpath('/html/body/div/div/main/div/div/div[2]/div[5]/div/div[1]/div/div[2]/div[2]/div[1]')
A.click();
and I get this error
Traceback (most recent call last):
File "C:\Users\User\Desktop\666.py", line 4, in <module>
A = browser.find_element_by_xpath('/html/body/div/div/main/div/div/div[2]/div[5]/div/div[1]/div/div[2]/div[2]/div[1]')
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 394, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
'value': value})['value']
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\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":"xpath","selector":"/html/body/div/div/main/div/div/div[2]/div[5]/div/div[1]/div/div[2]/div[2]/div[1]"}
(Session info: chrome=80.0.3987.149)
full xpath {/html/body/div/div/main/div/div/div[2]/div[5]/div/div1/div/div[2]/div[2]/div1}
html of element i want to click on
<div role="button" tabindex="0" class="group--options_block m3-animate--all" aria-label="Performance"><div class="group--options_block_title"><span><p class="group--options_block--name text-loader--content" tabindex="-1">Performance</p></span><p class="group--options_block-container_price text-loader--content price-not-included">£95,800</p></div></div>
im copying and pasting the full xpath of the element i want. is that not the correct way to do this?
edit:
if it works the range should be 367 not 379
Use following xpath
//div[#class='group--options_block_title']/span/p
OR
//p[contains(text(),'Performance')]
OR CSS selector
div[aria-label='Performance']
Don't forget to introduce Implicit or Explicit wait to avoid synchronization issue in your scripts. reference
Please refer below code sometime sites are taking too long while loading so would be great if you use WebDriverWait in your solution. Also its not good practice to use Abs XPath.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import time
driver = webdriver.Chrome(executable_path=r"C:\New folder\chromedriver.exe")
driver.get('https://www.tesla.com/en_gb/models/design#battery')
wait = WebDriverWait(driver,30)
element = wait.until(EC.element_to_be_clickable((By.XPATH, "//p[contains(text(),'Performance')]")))
print element.text
element.click()
element1 = wait.until(EC.presence_of_element_located((By.XPATH, "//span[contains(text(),'367')]")))
print element1.text
Output:

Selenium log-in on pop-up webpage without HTML

In my Selenium program, I use a google-chrome driver to access and log into my account on this webpage. The problem is that the log-in webpage is a program with a pop-up window and without any HTML code I can grab. Therefore I don't know how to type in my credentials.
I have looked around and have seen several proposals with 'actions' like
actions = ActionChains(driver)
actions.send_keys('skdkds')
actions.perform()
But the problem is that it doesn't type in anything, it only places the cursor in the first field. I guess this is part of the security of the program, but by being able to place the cursor in the right place, I should be able to send keys to the driver and then move along with a tab command. But I don't know how.
For a reproducible example:
from bs4 import BeautifulSoup
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 pandas as pd
import datetime
import time
import glob
import os
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get(link_mentionned_above) //then I am blocked
Updated
As mentionned by Azy_Crw4282, the problem is here handling alerts, however the driver doesn't recognize any alert because for driver.switch_to_alert() I get the error:
File "/usr/local/lib/python3.6/dist-packages/selenium/webdriver/common/alert.py", line 67, in text
return self.driver.execute(Command.W3C_GET_ALERT_TEXT)["value"]
File "/usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoAlertPresentException: Message: no such alert
Your code below is incorrect since it's not handling the prompt alert explicitly.
actions = ActionChains(driver)
actions.send_keys('skdkds')
actions.perform()
Change it as follows
actions.switchTo().alert().sendKeys("Username");
actions.switchTo().alert().sendKeys("Password");

Python Selenium - 'Unable to locate element' after made visible

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

selecting element in python selenium

I'm trying to log onto a webpage with python selenium. I've found an element and it is enabled, but when I try to send_keys() to it I get an error. The main thing (I think) in the error output is
selenium.common.exceptions.ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with
My code is
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import contextlib
with contextlib.closing(webdriver.Firefox()) as driver:
driver.get('http://www.etoro.com/au')
elem = driver.find_element_by_class_name('inputUsername')
print 'enabled:', elem.is_enabled()
print 'selected:', elem.is_selected()
elem.send_keys('myusername')
And the output is
enabled: True
selected: False
Traceback (most recent call last):
File "3_trying_again.py", line 10, in <module>
elem.send_keys('ianafterglow')
File "/Users/ian/miniconda/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 303, in send_keys
self._execute(Command.SEND_KEYS_TO_ELEMENT, {'value': typing})
File "/Users/ian/miniconda/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 385, in _execute
return self._parent.execute(command, params)
File "/Users/ian/miniconda/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 173, in execute
self.error_handler.check_response(response)
File "/Users/ian/miniconda/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 166, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with
Stacktrace:
at fxdriver.preconditions.visible (file:///var/folders/5b/ym07nh6d74gcn_773ynwqkth0000gn/T/tmpN1MV8l/extensions/fxdriver#googlecode.com/components/command-processor.js:8959:12)
at DelayedCommand.prototype.checkPreconditions_ (file:///var/folders/5b/ym07nh6d74gcn_773ynwqkth0000gn/T/tmpN1MV8l/extensions/fxdriver#googlecode.com/components/command-processor.js:11618:15)
at DelayedCommand.prototype.executeInternal_/h (file:///var/folders/5b/ym07nh6d74gcn_773ynwqkth0000gn/T/tmpN1MV8l/extensions/fxdriver#googlecode.com/components/command-processor.js:11635:11)
at DelayedCommand.prototype.executeInternal_ (file:///var/folders/5b/ym07nh6d74gcn_773ynwqkth0000gn/T/tmpN1MV8l/extensions/fxdriver#googlecode.com/components/command-processor.js:11640:7)
at DelayedCommand.prototype.execute/< (file:///var/folders/5b/ym07nh6d74gcn_773ynwqkth0000gn/T/tmpN1MV8l/extensions/fxdriver#googlecode.com/components/command-processor.js:11582:5)
So, what do I need to do?
To make the username field to be visible, you need to move cursor to the login link:
....
driver.get('http://www.etoro.com/au')
action = webdriver.ActionChains(driver)
action.move_to_element(driver.find_element_by_xpath(
'.//a[#class="top-link"]/span[text()="Login"]'
))
action.perform()
# TODO Need to wait until the `inputUsername` field is visible
elem = driver.find_element_by_class_name('inputUsername')
...
You can use explicit waits:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASSNAME, "inputUsername"))
)
...
I know that this problem is solved ,
I got stuck in similar problem and same error
I have fixed it by just make my script sleep for 2 seconds then resume it was just Connection speed problem
...
time.sleep(2)
...
don't forget to import time module
import time
wish that help anyone in future :D
I had similar issue, selenium was not able to focus and open the login modal. Instead it was focusing on the next element. This was the locator I was using:
elem = browser.find_element_by_xpath("//nav[2]/ul/li[3]/a").click()
I just changed [3] with [2] and it was able to locate the element and open the modal:
elem = browser.find_element_by_xpath("//nav[2]/ul/li[2]/a").click()

Categories