Selenium locate element fails when Chrome in background - python

This program works fine when you're focused on the window (Chrome), but when you switch to another window like Mozilla, or another app to continue doing your work, the Selenium fails to locate the element.
It should locate the element perfectly fine whether or not I open other apps over it, switch to other windows, and login without issues - that's what I want to accomplish so I can turn it into headless when it isn't giving me this error.
I tried to use driver waits too but to no avail.
The error I get:
selenium.common.exceptions.TimeoutException: Message:
Stacktrace:
Backtrace:
Ordinal0 [0x00986903+2517251]
Ordinal0 [0x0091F8E1+2095329]
Ordinal0 [0x00822848+1058888]
Ordinal0 [0x0084D448+1233992]
Ordinal0 [0x0084D63B+1234491]
Ordinal0 [0x00877812+1406994]
Ordinal0 [0x0086650A+1336586]
Ordinal0 [0x00875BBF+1399743]
Ordinal0 [0x0086639B+1336219]
Ordinal0 [0x008427A7+1189799]
Ordinal0 [0x00843609+1193481]
GetHandleVerifier [0x00B15904+1577972]
GetHandleVerifier [0x00BC0B97+2279047]
GetHandleVerifier [0x00A16D09+534521]
GetHandleVerifier [0x00A15DB9+530601]
Ordinal0 [0x00924FF9+2117625]
Ordinal0 [0x009298A8+2136232]
Ordinal0 [0x009299E2+2136546]
Ordinal0 [0x00933541+2176321]
BaseThreadInitThunk [0x770EFA29+25]
RtlGetAppContainerNamedObjectPath [0x77B47A9E+286]
RtlGetAppContainerNamedObjectPath [0x77B47A6E+238]
Code:
import tkinter as tk
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
import time
from time import sleep
root = tk.Tk()
app_width = 300
app_height = 320
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x = (screen_width / 2) - (app_width / 2)
y = (screen_height / 2) - (app_height / 2)
root.geometry(f'{app_width}x{app_height}+{int(x)}+{int(y)}')
testbtn_txt = tk.StringVar()
testbtn = tk.Button(root, textvariable=testbtn_txt, command=lambda:open_browser_func(), font="Arial", bg="#808080", fg="white", height=1, width=10)
testbtn_txt.set("Test")
testbtn.grid(row=10, column=0, columnspan=2, pady=5, padx=5)
def open_browser_func():
global driver
driver = webdriver.Chrome("C:\Program Files (x86)\chromedriver.exe")
driver.get("https://twitter.com/i/flow/login")
sleep(5)
loginuser = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="layers"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[5]/label/div/div[2]/div/input')))
loginuser.send_keys("Username")
sleep(5)
loginuser.send_keys(Keys.RETURN)
loginuser = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="layers"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[3]/div/label/div/div[2]/div[1]/input')))
loginuser.send_keys("Password")
sleep(5)
loginuser.send_keys(Keys.RETURN)
return driver
root.mainloop()
This is really annoying as it works sometimes, and sometimes not. I am unable to make this completely automated because of the error that happens when I switch to other processes.

Selenium needs to focus on both:
Browser Window
DOM Element
When you bring another window like Mozilla, or another app to the foreground and continue doing your work Selenium looses the focus from the Browser Context. Hence you see the error.
References
You can find a couple of relevant detailed discussions in:
Selenium stops when browser is manually interrupted
Way to open Selenium browser not overlapping my current browser
How to execute tests with selenium webdriver while browser is minimized
Sending selenium chrome instance to the background using Python

You should use either one of the below locators before jumping to XPath.
ID
name
classname
linkText
partialLinkText
tagName
css selector
xpath
Also, make sure that you should not be using absolute xpath, rather it should be relative xpath.
So, Instead of these
loginuser = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="layers"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[5]/label/div/div[2]/div/input')))
loginuser.send_keys("Username")
sleep(5)
loginuser.send_keys(Keys.RETURN)
loginuser = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="layers"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[3]/div/label/div/div[2]/div[1]/input')))
loginuser.send_keys("Password")
sleep(5)
loginuser.send_keys(Keys.RETURN)
Use this:
wait = WebDriverWait(driver, 30)
loginuser = wait.until(EC.visibility_of_element_located((By.NAME, "text")))
loginuser.send_keys("Username", Keys.RETURN)
loginPassword = wait.until(EC.visibility_of_element_located((By.NAME, "password")))
loginPassword.send_keys("password here", Keys.RETURN)

Related

How to solve selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element:

I'm trying to code a bot that will automate a login on a certain page using selenium. I keep getting the same error, and I don't know how to fix it. Please help :=)
Here's the code:
# Importing everything #
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
# PATH + Driver Setup #
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
# Getting All Requirements #
driver.get("https://ytmonster.net/login")
time.sleep(5)
imputUsername = driver.find_element(By.ID, "inputUsername")
imputPassword = driver.find_element(By.ID, "inputPassword")
linkClick = driver.find_element(By.CLASS_NAME, "btn btn-success")
# Executing script #
imputUsername.send_keys("mymail#gmail.com")
imputPassword.send_keys("mypassword")
linkClick.click
And here is the error that I get:
C:\Users\Xera\Desktop\YtMonster Bot.py:9: DeprecationWarning: executable_path has been deprecated, please pass in a Service object
driver = webdriver.Chrome(PATH)
DevTools listening on ws://127.0.0.1:51847/devtools/browser/a848e7ed-d31d-4415-96c5-1a28a4729a17
[8664:1220:0815/155348.366:ERROR:device_event_log_impl.cc(214)] [15:53:48.364] Bluetooth: bluetooth_adapter_winrt.cc:1074 Getting Default Adapter failed.
Traceback (most recent call last):
File "C:\Users\Xera\Desktop\YtMonster Bot.py", line 16, in <module>
linkClick = driver.find_element(By.CLASS_NAME, "btn btn-success")
File "C:\Users\Xera\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 856, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "C:\Users\Xera\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 434, in execute
self.error_handler.check_response(response)
File "C:\Users\Xera\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 243, 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":".btn btn-success"}
(Session info: chrome=104.0.5112.81)
Stacktrace:
Backtrace:
Ordinal0 [0x00CA78B3+2193587]
Ordinal0 [0x00C40681+1771137]
Ordinal0 [0x00B541A8+803240]
Ordinal0 [0x00B824A0+992416]
Ordinal0 [0x00B8273B+993083]
Ordinal0 [0x00BAF7C2+1177538]
Ordinal0 [0x00B9D7F4+1103860]
Ordinal0 [0x00BADAE2+1170146]
Ordinal0 [0x00B9D5C6+1103302]
Ordinal0 [0x00B777E0+948192]
Ordinal0 [0x00B786E6+952038]
GetHandleVerifier [0x00F50CB2+2738370]
GetHandleVerifier [0x00F421B8+2678216]
GetHandleVerifier [0x00D317AA+512954]
GetHandleVerifier [0x00D30856+509030]
Ordinal0 [0x00C4743B+1799227]
Ordinal0 [0x00C4BB68+1817448]
Ordinal0 [0x00C4BC55+1817685]
Ordinal0 [0x00C55230+1856048]
BaseThreadInitThunk [0x766A6739+25]
RtlGetFullPathName_UEx [0x779F90AF+1215]
RtlGetFullPathName_UEx [0x779F907D+1165]
How can I fix this? I tried everything but didn't find any answers... Thanks again for the help! :)
You can't pass multiple classnames as argument using By.CLASS_NAME as:
find_element(By.CLASS_NAME, "classname1 classname2")
Solution
To automate the login process on the webpage you can use locator strategies:
Using CSS_SELECTOR:
driver.execute("get", {'url': 'https://ytmonster.net/login'})
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#inputUsername"))).send_keys("Xera#stackoverflow.com")
driver.find_element(By.CSS_SELECTOR, "input#inputPassword").send_keys("XeraXera")
driver.find_element(By.CSS_SELECTOR, "button.btn.btn-success").click()
Using XPATH:
driver.execute("get", {'url': 'https://ytmonster.net/login'})
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#id='inputUsername']"))).send_keys("Xera#stackoverflow.com")
driver.find_element(By.XPATH, "//input[#id='inputPassword']").send_keys("XeraXera")
driver.find_element(By.XPATH, "//button[#class='btn btn-success']").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
Browser Snapshot:
This is because your page elements get changed after you manipulate it using Selenium. Try other ways to access the desired element such as xpath. Selecting by class often causes this exception as the class of your html elements can change. For example, once a tab is clicked, the class can change to something like: tab-button active, while prior to the clicking, it was something like: tab-button.
I recommend using xpath. It is very powerful as it enhances your ability to access items in a relative way from each other. You can for example say I want the i-th children of my first row inside a table inside body inside html tag.
This is one way of accomplishing your task:
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options as Firefox_Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support import expected_conditions as EC
import time as t
firefox_options = Firefox_Options()
# firefox_options.add_argument("--width=1500")
# firefox_options.add_argument("--height=500")
# firefox_options.headless = True
driverService = Service('chromedriver/geckodriver')
browser = webdriver.Firefox(service=driverService, options=firefox_options)
url = 'https://ytmonster.net/login'
browser.get(url)
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#id='inputUsername']"))).send_keys('my_great_username')
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#id='inputPassword']"))).send_keys('my really bad password')
print('wrote in my user and pass')
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[text()='Login']"))).click()
print('clicked the login button!')
The setup is Firefox /geckodriver on Linux, however you can adapt it to your own system, just observe the imports, and the part after defining the browser/driver.
Selenium docs: https://www.selenium.dev/documentation/

Python Selenium - How to select this button and click it

I've been trying to get this button selected and click it in order to add a trading view strategy to a chart. I've automated everything up to this point including the locating and clicking of similar buttons. This one seems a bit finicky. Here is the code that I've already implemented that works (except for the 'Add To Chart' button)
WHAT WORKS ON OTHER BUTTONS
# Select the strategy
select_strat = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.CLASS_NAME, 'title-phaedJZ1')))
select_strat.click()
# Close the strategy window
close_strat_window = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.CLASS_NAME, 'close-tuOy5zvD')))
close_strat_window.click()
WHAT I'M TRYING TO LOCATE AND CLICK
WHAT I'VE ALREADY TRIED IMPLEMENTING
# Add strat to chart
# button-TuYnJRjv rightControlsBlock__button-TuYnJRjv button-9pA37sIi isInteractive-9pA37sIi newStyles-9pA37sIi ace_layer ace_cursor-layer ace_hidden-cursors
add_to_chart = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//*[#id="tv-script-pine-editor-header-root"]/div[1]/div/div[2]/div[3]')))
add_to_chart.click()
Note - I've tried every combination of the comment of the class below for CLASS_NAME
# Add strat to chart
# button-TuYnJRjv rightControlsBlock__button-TuYnJRjv button-9pA37sIi isInteractive-9pA37sIi newStyles-9pA37sIi ace_layer ace_cursor-layer ace_hidden-cursors
add_to_chart = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'button-TuYnJRjv')))
add_to_chart.click()
REQUEST FROM COMMENTS FOR STACKTRACE
pipenv run python .\dev\tv_data_collector.py
Loading .env environment variables...
C:\Users\REDACTED\Documents\Trading\Automation\dev\tv_data_collector.py:20: DeprecationWarning: executable_path has been deprecated, please pass in a Service object
driver = webdriver.Chrome(executable_path=path, chrome_options=options)
C:\Users\tgall\Documents\Trading\Automation\dev\tv_data_collector.py:20: DeprecationWarning: use options instead of chrome_options
driver = webdriver.Chrome(executable_path=path, chrome_options=options)
DevTools listening on ws://127.0.0.1:65270/devtools/browser/93062f9b-ac9d-465e-9471-df4c5098e655
[26756:18156:0817/175454.408:ERROR:device_event_log_impl.cc(214)] [17:54:54.409] USB: usb_device_handle_win.cc:1048 Failed to read descriptor from node connection: A device attached to the system is not functioning. (0x1F)
Traceback (most recent call last):
File "C:\Users\REDACTED\Documents\Trading\Automation\dev\tv_data_collector.py", line 126, in <module>
tv_get_security(driver)
File "C:\Users\REDACTED\Documents\Trading\Automation\dev\tv_data_collector.py", line 73, in tv_get_security
script_search = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'input-CcsqUMct')))
File "C:\Users\REDACTED\.virtualenvs\Automation--luj7l49\lib\site-packages\selenium\webdriver\support\wait.py", line 90, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
Stacktrace:
Backtrace:
Ordinal0 [0x006E78B3+2193587]
Ordinal0 [0x00680681+1771137]
Ordinal0 [0x005941A8+803240]
Ordinal0 [0x005C24A0+992416]
Ordinal0 [0x005C273B+993083]
Ordinal0 [0x005EF7C2+1177538]
Ordinal0 [0x005DD7F4+1103860]
Ordinal0 [0x005EDAE2+1170146]
Ordinal0 [0x005DD5C6+1103302]
Ordinal0 [0x005B77E0+948192]
Ordinal0 [0x005B86E6+952038]
GetHandleVerifier [0x00990CB2+2738370]
GetHandleVerifier [0x009821B8+2678216]
GetHandleVerifier [0x007717AA+512954]
GetHandleVerifier [0x00770856+509030]
Ordinal0 [0x0068743B+1799227]
Ordinal0 [0x0068BB68+1817448]
Ordinal0 [0x0068BC55+1817685]
Ordinal0 [0x00695230+1856048]
BaseThreadInitThunk [0x76466739+25]
RtlGetFullPathName_UEx [0x778890AF+1215]
RtlGetFullPathName_UEx [0x7788907D+1165]
This error has not prevented anything from working going forward (until now perhaps.. not sure)
If you are clicking on the button then you should use element to be clickable instead of presece of element like below:
add_to_chart = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, 'button-TuYnJRjv')))
add_to_chart.click()
OR
add_to_chart = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[normalize-space()='Add to chart']")))
add_to_chart.click()
OR
add_to_chart = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(text(),'Add to chart')]")))
add_to_chart.click()
For DeprecationWarning the Selenium v4 compatible Code Block
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://www.google.com")
For more info visit this
in your picture, div.js-button-text.text-9pA37sli is CSS SELECTOR
so
EC.presence_of_element_located((By.CLASS_NAME, 'button-TuYnJRjv'))
into
EC.presence_of_element_located((By.CSS_SELECTOR, 'div.js-button-text.text-9pA37sli'))

Tiktok: Selenium unable to find upload area

As the title suggests, my bot is unable to find the upload area on the tiktok website.
driver.get("https://www.tiktok.com/upload/")
time.sleep(5)
upld = driver.find_element(By.XPATH, "//*[#id='root']/div/div/div/div/div[2]/div[1]/div/div/div[4]/button")
upld.send_keys(r"C:\Users\Marius\final.mp4")
The error I am getting while running the code is:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id='root']/div/div/div/div/div[2]/div[1]/div/div/div[4]/button"}
(Session info: chrome=103.0.5060.134)
Stacktrace:
Backtrace:
Ordinal0 [0x01155FD3+2187219]
Ordinal0 [0x010EE6D1+1763025]
Ordinal0 [0x01003E78+802424]
Ordinal0 [0x01031C10+990224]
Ordinal0 [0x01031EAB+990891]
Ordinal0 [0x0105EC92+1174674]
Ordinal0 [0x0104CBD4+1100756]
Ordinal0 [0x0105CFC2+1167298]
Ordinal0 [0x0104C9A6+1100198]
Ordinal0 [0x01026F80+946048]
Ordinal0 [0x01027E76+949878]
GetHandleVerifier [0x013F90C2+2721218]
GetHandleVerifier [0x013EAAF0+2662384]
GetHandleVerifier [0x011E137A+526458]
GetHandleVerifier [0x011E0416+522518]
Ordinal0 [0x010F4EAB+1789611]
Ordinal0 [0x010F97A8+1808296]
Ordinal0 [0x010F9895+1808533]
Ordinal0 [0x011026C1+1844929]
BaseThreadInitThunk [0x7615FA29+25]
RtlGetAppContainerNamedObjectPath [0x77847A9E+286]
RtlGetAppContainerNamedObjectPath [0x77847A6E+238]
I've tried running the bot on my other device and it worked with no flaws, but it doesnt seem to work when I try it with selenium for some reason. The chrome version is the same on all devices and on selenium as well.
I've tried css-selector and class find methods, but they still return no result.
Any help is appreciated.
Try this:
# There is an iframe on the page...
iframe = driver.find_element(By.CSS_SELECTOR, 'iframe')
driver.switch_to.frame(iframe)
# Wait until page loads...
time.sleep(3)
# Select the input file and send the filename...
upload = driver.find_element(By.CSS_SELECTOR, 'input[type="file"]')
video_path = 'C:/Users/my_video.mp4'
upload.send_keys(video_path)
Because the content you are looking for in within an IFrame, Selenium XPath searches, unlike Google Chrome's Dev Tool XPath seaches, will not go into the IFrame. For this reason, all you need to do is switch iFrames and the code should work as expected.
iframe = driver.find_element(By.CSS_SELECTOR, 'iframe')
driver.switch_to.frame(iframe)
Note: WebDriverWait will do nothing to fix the problem as the page has already fully loaded.
As the locator strategies worked on your other device presumably the locator is flawless but ideally to send a character sequence to the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[#id='root']/div/div/div/div/div[2]/div[1]/div/div/div[4]/button"))).send_keys("C:\Users\Marius\final.mp4")
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

Error finding element with selenium python of transfer market website?(tried with xpath,class name etc) but nothing works

Hi Dear Programmers and webscrapers.I have tried so much times to locate the element and then press it but it always gives me error in selenium.I have treid using XPATH,class name and id of the element is not present so I tried with multiple things but nothing works and returns me an error.
This is the website link that I want to scrap.
Website to scrap
Here is the element that I wanted to scrap.
This element had class selector-title so I tried with class name and also with xpath of this element and with its sub elements also but unfortunately was not able to locate it.
Here is the code that i used.This code is working for other functions like I have located search box and have searched pressed button it works.Right.Where it dosent work is the element I have been trying it to work.Please let me know what mistake is from mine side so this can be workable or I can locate it and then click on it.
Actually this I have to do for web scraping the data of all the players in a club or in a league so for that I have to select the league of country first then I will be able to scrap the data so its very much important for me to actually be able to locate and click the marked element.Please help me if any one of you can.Thanks.
XPATH of the marked element
//*[#id="main"]/header/div[3]/tm-quick-select-bar//div/tm-quick-select[1]/div/div
Here is my code
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait as wait
os.environ['PATH'] += r"C:/ChromeDriver"
browser = webdriver.Chrome()
browser.get("https://www.transfermarkt.us/")
element = browser.find_element(By.XPATH, '//*[#id="schnellsuche"]/input[1]')
element.send_keys("J1 League")
time.sleep(5)
# element2 = browser.find_element(By.XPATH, '//*[#id="main"]/header/div[3]/tm-quick-select-bar//div/tm-quick-select[1]/div/div[1]/strong/text()')
# element2.click()
button = wait(browser, 10).until(EC.presence_of_element_located(
(By.CLASS_NAME, 'selector-title')))
button.click()
time.sleep(10)
The error I get is the browser instantly closes as soon as it reaches the last element target element to click
DevTools listening on ws://127.0.0.1:61330/devtools/browser/d6f23f8f-6bea-41dd-8500-08f85c9cb502
[18424:9224:0523/200949.930:ERROR:device_event_log_impl.cc(214)] [20:09:49.929] USB: usb_device_handle_win.cc:1049 Failed to read descriptor from node connection: A device attached to the system is not functioning. (0x1F)
[18424:9224:0523/200949.936:ERROR:device_event_log_impl.cc(214)] [20:09:49.935] USB: usb_device_handle_win.cc:1049 Failed to read descriptor from node connection: A device attached to the system is not functioning. (0x1F)
[18424:9224:0523/200949.951:ERROR:device_event_log_impl.cc(214)] [20:09:49.951] Bluetooth: bluetooth_adapter_winrt.cc:1075 Getting Default Adapter failed.
Traceback (most recent call last):
File "d:\WeBScraping\FreecodecampWebScrapingTutorial\selenium_tutorial_freecodecamp\scrapingtarget.py", line 18, in <module>
button = wait(browser, 10).until(EC.presence_of_element_located(
File "C:\Users\bilal\AppData\Roaming\Python\Python310\site-packages\selenium\webdriver\support\wait.py", line 89, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
Stacktrace:
Backtrace:
Ordinal0 [0x00E1B8F3+2406643]
Ordinal0 [0x00DAAF31+1945393]
Ordinal0 [0x00C9C748+837448]
Ordinal0 [0x00CC92E0+1020640]
Ordinal0 [0x00CC957B+1021307]
Ordinal0 [0x00CF6372+1205106]
Ordinal0 [0x00CE42C4+1131204]
Ordinal0 [0x00CF4682+1197698]
Ordinal0 [0x00CE4096+1130646]
Ordinal0 [0x00CBE636+976438]
Ordinal0 [0x00CBF546+980294]
GetHandleVerifier [0x01089612+2498066]
GetHandleVerifier [0x0107C920+2445600]
GetHandleVerifier [0x00EB4F2A+579370]
GetHandleVerifier [0x00EB3D36+574774]
Ordinal0 [0x00DB1C0B+1973259]
Ordinal0 [0x00DB6688+1992328]
Ordinal0 [0x00DB6775+1992565]
Ordinal0 [0x00DBF8D1+2029777]
BaseThreadInitThunk [0x76CDFA29+25]
RtlGetAppContainerNamedObjectPath [0x76F57A7E+286]
RtlGetAppContainerNamedObjectPath [0x76F57A4E+238]
Not sure if I understood you correctly, but the code below return the following text "United States".
import time
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait as wait
driver = webdriver.Chrome(options=options, desired_capabilities=capabilities)
# open url:
driver.get('https://www.transfermarkt.us/')
# switch to cookies frame
wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "sp_message_iframe_575847")))
time.sleep(3)
# click "Accept" cookies button
driver.find_element(By.XPATH, '//button[#title="ACCEPT ALL"]').click()
time.sleep(3)
# go back to main frame
driver.switch_to.default_content()
# here's the trick, what you are looking for is inside a "shadow-root" DOM so to access it you need to execute the script and then use CSS selector, I don't think XPATH works here:
country = driver.execute_script("return document.querySelector('tm-quick-select-bar').shadowRoot.querySelector('div > tm-quick-select:nth-child(2) > div > div > strong')")
# print
print(country.text)
# close the driver
driver.close()

How to find and click on elements that aren't there depending on page size with selenium in python

I am working on a project to automate the process of scheduling my tee time each week. Basically the times open up at 5AM a week ahead so instead of wakng up at 5AM every week I want it to automate the process.
I have run into a problem with selenium. The courses webpage loads easily, and the login is fine, but once I get to the home page I can't click one of the menu buttons. I keep getting this error:
Exception Raised Message: element not interactable
(Session info: chrome=100.0.4896.127)
Stacktrace:
Backtrace:
Ordinal0 [0x00527413+2389011]
Ordinal0 [0x004B9F61+1941345]
Ordinal0 [0x003AC520+836896]
Ordinal0 [0x003DA1F3+1024499]
Ordinal0 [0x003CFF93+982931]
Ordinal0 [0x003F414C+1130828]
Ordinal0 [0x003CF974+981364]
Ordinal0 [0x003F4364+1131364]
Ordinal0 [0x00404302+1196802]
Ordinal0 [0x003F3F66+1130342]
Ordinal0 [0x003CE546+976198]
Ordinal0 [0x003CF456+980054]
GetHandleVerifier [0x006D9632+1727522]
GetHandleVerifier [0x0078BA4D+2457661]
GetHandleVerifier [0x005BEB81+569713]
GetHandleVerifier [0x005BDD76+566118]
Ordinal0 [0x004C0B2B+1968939]
Ordinal0 [0x004C5988+1989000]
Ordinal0 [0x004C5A75+1989237]
Ordinal0 [0x004CECB1+2026673]
BaseThreadInitThunk [0x779CFA29+25]
RtlGetAppContainerNamedObjectPath [0x77E57A7E+286]
RtlGetAppContainerNamedObjectPath [0x77E57A4E+238]
I have tried to click this ForeTees button so many different ways and I can't figure it out.
from config.secrets import COURSE_URL
from login import login
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.common import exceptions
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from decorators import base_logger
import time
# Path to Chrome Driver
CHROMEDRIVER_PATH = r"C:\\webdriver\\chromedriver.exe"
FIREFOXDRIVER_PATH = r"C:\\webdriver\\geckodriver.exe"
class HomePageDropDown:
"""This class is for locators on the Home Page"""
DROP_DOWN_MENU = ".ui-link"
DD_BTN_ATTEMPT_1 = "//a[contains(#href, '#menu']"
DD_FORETEES_BTN_XPATH = "//span[#class='smartphone-nav-heading'][normalize-space()='Foretees']"
DD_BUTTON = "//div[#id='mm-menu-link']"
class HomePageLocators:
"""This class is for locators on the members home page after logging in"""
FORETEES_BUTTON_PARTIAL = "Foretees"
FORETEES_BUTTON_XPATH = "//span[text()[normalize-space()='Foretees']]"
FORETEES_XPATH_LONG = "//div[#id='textured-cssmenu']/ul[1]/li[5]/a[1]/span[1]"
FORETEES_BUTTON_CSS_SELECTOR = "div#textured-cssmenu>ul>li:nth-of-type(5)>a>span"
FORETEES_BUTTON_PAGE_ID = "//*[#data-pageid='53']"
# Error Message: selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
FORETEES_BUTTON_XPATH_1 = "//span[#class='textured-nav-heading textured-nav-heading-unselected'][normalize-space()='Foretees']"
FORETEES_BUTTON_XPATH_2 = "//a/span[contains(#class,'textured-nav-heading textured-nav-heading-unselected')][normalize-space()='Foretees']"
#base_logger()
def click_foretees(driver):
locator = HomePageLocators.FORETEES_BUTTON_XPATH_2
try:
element = driver.find_element(By.XPATH, locator)
element.click()
return element
except exceptions.ElementNotInteractableException as ni:
print(f"Exception Raised {ni}")
except exceptions.NoSuchElementException as ne:
print(f"Exception Raised {ne}")
except exceptions.ElementNotVisibleException as nv:
print(f"Exception Raised {nv}")
except AttributeError as ae:
print(f"Error Raised {ae}")
#base_logger()
def click_drop_down(driver):
locator = HomePageDropDown.DD_BUTTON
try:
element = driver.find_element(By.XPATH, locator)
element.click()
return element
except exceptions.ElementNotInteractableException as se:
print(f"Exception Raised {se}")
except AttributeError as ae:
print("Element doesn't have that attribute ")
#base_logger()
def home_page(driver):
try:
driver.find_element(By.CSS_SELECTOR, HomePageLocators.DROP_DOWN_MENU).click_and_hold()
driver.implicitly_wait(10)
except exceptions.ElementNotInteractableException as se:
print(se)
if __name__ == '__main__':
# Create a webdriver instance
driver = webdriver.Chrome(CHROMEDRIVER_PATH)
# Open the url with driver
driver.get(COURSE_URL)
# ================================================================ #
# RUN INITIAL PROGRAM FUNCTIONS:
# ================================================================ #
# run login function
login(driver)
# wait for page to load
driver.implicitly_wait(10)
# run home_page function
click_foretees(driver)
# click_drop_down(driver)
# ================================================================ #
# close Browser
driver.close()
I tried to put all the different xpath's and css selectors I tried but I know there are a lot more I am missing.
I would really appreciate any help I can get.

Categories