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

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/

Related

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

Can't find an element by its xpath (slenium in python)

Here's the full code
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
words = list() #initialize a words list
with open("sorted_words_list.txt", 'r') as data_set: #opens the .txt file
for line in data_set: #loops through every line in the .txt file
words.append(line.strip('\n')) #removes the '\n' from the line and appends it to the word list
PATH = 'C:\Program Files (x86)\chromedriver.exe' #identifies the path for the driver
driver = webdriver.Chrome(PATH) #creates the driver
driver.implicitly_wait(0.5)
driver.get('https://jklm.fun/KNVC') #opens the web page
driver.implicitly_wait(5)
name_box = driver.find_element(by=By.XPATH, value="//INPUT[#class='styled nickname']") #finds the box to input the name
name_box.clear() #removes whatever name is in the box
name_box.send_keys("SasuX") #inputs the name SasuX in the box
name_box.send_keys(Keys.RETURN) #enters the values (enters the game room)
driver.implicitly_wait(1)
syllable = ''
while True:
try:
syllable = driver.find_element(by=By.XPATH, value="//DIV[#class='syllable']").text
print(syllable)
except Exception as e:
print(e)
time.sleep(1)
I was trying to find the text contained in a div with its xpath, but i get a "Unable to locate element" error.
The problem it's not the fact that the page has to load, and this is because I'm running an infinite loop that keeps checking.
I think the problem might be the fact that I wrote the relative xpath by myself, and this is because the chrome inspection tool won't let me copy the relative xpath, but only the absolute xpath. I tryed using the absolute xpath, but it's not working.
I would be glad is someone could help me.
EDIT:
I had to change the code a little bit, so that I could show the full error.
Here's the modified code:
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
import time
words = list() #initialize a words list
with open("sorted_words_list.txt", 'r') as data_set: #opens the .txt file
for line in data_set: #loops through every line in the .txt file
words.append(line.strip('\n')) #removes the '\n' from the line and appends it to the word list
PATH = 'C:\Program Files (x86)\chromedriver.exe' #identifies the path for the driver
driver = webdriver.Chrome(PATH) #creates the driver
driver.implicitly_wait(0.5)
driver.get('https://jklm.fun/VWMS') #opens the web page
driver.implicitly_wait(5)
name_box = driver.find_element(by=By.XPATH, value="//INPUT[#class='styled nickname']") #finds the box to input the name
name_box.clear() #removes whatever name is in the box
name_box.send_keys("SasuX") #inputs the name SasuX in the box
name_box.send_keys(Keys.RETURN) #enters the values (enters the game room)
driver.implicitly_wait(10)
syllable = driver.find_element(by=By.XPATH, value="//DIV[#class='syllable']")
print(syllable.text)
And here's the full error I'm getting in the console:
Traceback (most recent call last):
File "c:\Users\Samuel\code\bots\JKLM_bot_py\main.py", line 27, in <module>
syllable = driver.find_element(by=By.XPATH, value="//DIV[#class='syllable']")
File "C:\Users\Samuel\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 1251, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "C:\Users\Samuel\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 430, in execute
self.error_handler.check_response(response)
File "C:\Users\Samuel\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 247, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//DIV[#class='syllable']"}
(Session info: chrome=102.0.5005.115)
Stacktrace:
Backtrace:
Ordinal0 [0x00A2D953+2414931]
Ordinal0 [0x009BF5E1+1963489]
Ordinal0 [0x008AC6B8+837304]
Ordinal0 [0x008D9500+1021184]
Ordinal0 [0x008D979B+1021851]
Ordinal0 [0x00906502+1205506]
Ordinal0 [0x008F44E4+1131748]
Ordinal0 [0x00904812+1198098]
Ordinal0 [0x008F42B6+1131190]
Ordinal0 [0x008CE860+976992]
Ordinal0 [0x008CF756+980822]
GetHandleVerifier [0x00C9CC62+2510274]
GetHandleVerifier [0x00C8F760+2455744]
GetHandleVerifier [0x00ABEABA+551962]
GetHandleVerifier [0x00ABD916+547446]
Ordinal0 [0x009C5F3B+1990459]
Ordinal0 [0x009CA898+2009240]
Ordinal0 [0x009CA985+2009477]
Ordinal0 [0x009D3AD1+2046673]
BaseThreadInitThunk [0x760E6739+25]
RtlGetFullPathName_UEx [0x77128FEF+1215]
RtlGetFullPathName_UEx [0x77128FBD+1165]
I managed to solve the problem. The problem is that I was trying to find an element that was inside an iframe. So I just had to add a part of code that switches to the iframe.
iframe = driver.find_element(by=By.XPATH, value="//iframe[#src='https://falcon.jklm.fun/games/bombparty']")
driver.switch_to.frame(iframe)

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()

Selenium locate element fails when Chrome in background

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)

Categories