Selenium can't click on a element in an iframe - python

So im trying to click a button in an iframe but it just errors saying that the button can't be found.
recaptcha = driver.find_element_by_tag_name('iframe')
driver.switch_to.frame(recaptcha)
submit1 = driver.find_element_by_id('recaptcha-anchor')
actions = ActionChains(driver)
actions.move_to_element(submit1)
actions.click(submit1).perform()
time.sleep(3)
driver.find_element_by_id('recaptcha-audio-button').click()
On the last line I try to get an element by id recaptcha-audio-button.
As I said above it just errors with that it can't find it.
The website that I am trying to do this with is: https://patrickhlauke.github.io/recaptcha/
Why can't I click this button?
Thanks, Ira.
EDIT
Here is the error
Traceback (most recent call last):
File "main.py", line 62, in <module>
driver.find_element_by_id('recaptcha-audio-button').click()
File "/home/ira/.local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 269, in find_element_by_id
return self.find_element(by=By.ID, value=id_)
File "/home/ira/.local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 752, in find_element
'value': value})['value']
File "/home/ira/.local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 236, in execute
self.error_handler.check_response(response)
File "/home/ira/.local/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 192, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: An element could not be located on the page using the given search parameters.

Element is in different iframe so you can do:
switch to main window
find all iframes and switch to second iframe
find and click your button
Code:
# go back to main window
driver.switch_to.default_content()
# find all frames and switch to second frame
all_frames = driver.find_elements_by_tag_name('iframe')
driver.switch_to.frame(all_frames[1])
driver.find_element_by_id('recaptcha-audio-button').click()
Minimal working code so everyone can copy and test it
import selenium.webdriver
import time
driver = selenium.webdriver.Firefox()
driver.get('https://patrickhlauke.github.io/recaptcha/')
recaptcha = driver.find_element_by_tag_name('iframe')
driver.switch_to.frame(recaptcha)
submit1 = driver.find_element_by_id('recaptcha-anchor')
actions = selenium.webdriver.ActionChains(driver)
actions.move_to_element(submit1)
actions.click(submit1).perform()
time.sleep(3)
# go back to main window
driver.switch_to.default_content()
# find all frames and switch to second frame
all_frames = driver.find_elements_by_tag_name('iframe')
driver.switch_to.frame(all_frames[1])
driver.find_element_by_id('recaptcha-audio-button').click()

Related

Updating facebook post using Selenium: error- element not found but i can find in my browser

i am trying to post on facebook wall using selenium in python. I am able to login but after login it cant find class name of status box which i copied from browser
here is my code-
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
user_name = "email"
password = "password"
msg = "hi i am new here"
driver = webdriver.Firefox()
driver.get("https://www.facebook.com")
element = driver.find_element_by_id("email")
element.send_keys(user_name)
element = driver.find_element_by_id("pass")
element.send_keys(password)
element.send_keys(Keys.RETURN)
time.sleep(5)
post_box = driver.find_element_by_class_name("a8c37x1j ni8dbmo4 stjgntxs l9j0dhe7")
post_box.click()
time.sleep(5)
post_box.send_keys(msg)
the snapshot of code i copied from browser is attached as image here
here is error i recived-
Traceback (most recent call last):
File "C:/Users/rosha/Desktop/facebook bot.py", line 17, in <module>
post_box = driver.find_element_by_class_name("a8c37x1j ni8dbmo4 stjgntxs l9j0dhe7")
File "C:\ProgramData\Anaconda3\envs\facebook bot.py\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:\ProgramData\Anaconda3\envs\facebook bot.py\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "C:\ProgramData\Anaconda3\envs\facebook bot.py\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\ProgramData\Anaconda3\envs\facebook bot.py\lib\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: .a8c37x1j ni8dbmo4 stjgntxs l9j0dhe7
try to find element by Xpath for example:
driver.find_element(By.XPATH, '//button[text()="Some text"]')
to find the xpath from the browser, just right click on something in the webpage and press inspect after that right click, a menu will appear, navigate to copy then another menu will appear, press copy fullpath.
check this https://selenium-python.readthedocs.io/locating-elements.html
The problem is that driver.find_element_by_class_name() can be used for one class, and not multiple classes as you have: a8c37x1j ni8dbmo4 stjgntxs l9j0dhe7 which are multiple classes separated by spaces.
Refer to the solution suggested here, it suggests using find_elements_by_xpath or find_element_by_css_selector.

selenium wedriver program can not go on

I am trying to use webdriver to click the login button and the page has transformed correctly.but the program stop and occured the proplem "selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable"
and this is the code where occured problems
browser.find_element_by_xpath(
'//*[#id="emap-rsids-content"]/div/div[3]/div/div[1]/div/div/div/input').send_keys(uid)
browser.find_element_by_xpath(
'//*[#id="emap-rsids-content"]/div/div[3]/div/div[2]/div/div/div/input').send_keys(pwd)
# click to sign in
browser.find_element_by_xpath('//*[#id="emap-rsids-content"]/div/div[3]/div/div[3]/div/button').send_keys(Keys.ENTER)
time.sleep(3)
browser.find_element_by_xpath('/html/body/main/article/section[1]/div/div/div/div[2]/div/div/div[2]/div[2]').click()
this is the traceback
Traceback (most recent call last):
File "C:/Users/14638/Desktop/auto_sign_zzu_jksb-master/auto_sign.py", line 68, in sign_in
time.sleep(3)
File "C:\Users\14638\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\webelement.py", line 80, in click
self._execute(Command.CLICK_ELEMENT)
File "C:\Users\14638\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\webelement.py", line 633, in _execute
return self._parent.execute(command, params)
File "C:\Users\14638\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\14638\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
(Session info: chrome=83.0.4103.116)
the line 68 is time.sleep(3), the click works and transform to a new page,but it still occured that the button element is interctable.
I have try two methods, one is
'''
browser.find_element_by_xpath('//*[#id="emap-rsids-content"]/div/div[3]/div/div[3]/div/button').click()
'''
and another is
'''
pages=browser.find_element_by_xpath('//*[#id="emap-rsids-content"]/div/div[3]/div/div[3]/div/button')
browser.execute_script("arguments[0].click();", pages)
'''
but still not work
I think you are trying to click the element which is not completely loaded.What you have to do is wait till that happens.
First import these files
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
Then add this after logging in.
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, '/html/body/main/article/section[1]/div/div/div/div[2]/div/div/div[2]/div[2]')))
Then do
browser.find_element_by_xpath('/html/body/main/article/section[1]/div/div/div/div[2]/div/div/div[2]/div[2]').click()
You need to update the page_source:
browser.find_element_by_xpath(
'//*[#id="emap-rsids-content"]/div/div[3]/div/div[1]/div/div/div/input').send_keys(uid)
browser.find_element_by_xpath(
'//*[#id="emap-rsids-content"]/div/div[3]/div/div[2]/div/div/div/input').send_keys(pwd)
# click to sign in
time.sleep(5) # add some time to load the page
browser.get(browser.current_url)
time.sleep(1)
browser.find_element_by_xpath('//*[#id="emap-rsids-content"]/div/div[3]/div/div[3]/div/button').send_keys(Keys.ENTER)
time.sleep(3)
browser.find_element_by_xpath('/html/body/main/article/section[1]/div/div/div/div[2]/div/div/div[2]/div[2]').click()

Selenium Webdriver :- Element Not Interactable Exception for the search option

I am trying to fill in the search input type box with value "fab" and then I want to display the next url with that keyword but I am getting this error for element not interactable. How can I solve this?
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome(executable_path='C:\\Users\\Mansi Dhingra\\Downloads\\chromedriver')
driver.get("https://www.thenational.ae/search?q=")
print(driver.title)
driver.implicitly_wait(10)
search_bar = driver.find_element_by_xpath('//input[#name="q"]')
print(search_bar)
search_bar.clear()
search_bar.send_keys("fab")
search_bar.send_keys(Keys.RETURN)
print(driver.current_url)
driver.close()
Error:-
Traceback (most recent call last): File "C:/Users/Mansi
Dhingra/Desktop/Projects/api/news/news_python.py", line 10, in
search_bar.clear() File "C:\Users\Mansi Dhingra\Desktop\Projects\api\venv\lib\site-packages\selenium\webdriver\remote\webelement.py",
line 95, in clear
self._execute(Command.CLEAR_ELEMENT) File "C:\Users\Mansi Dhingra\Desktop\Projects\api\venv\lib\site-packages\selenium\webdriver\remote\webelement.py",
line 633, in _execute
return self._parent.execute(command, params) File "C:\Users\Mansi
Dhingra\Desktop\Projects\api\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py",
line 321, in execute
self.error_handler.check_response(response) File "C:\Users\Mansi Dhingra\Desktop\Projects\api\venv\lib\site-packages\selenium\webdriver\remote\errorhandler.py",
line 242, in check_response
raise exception_class(message, screen, stacktrace) selenium.common.exceptions.ElementNotInteractableException: Message:
element not interactable (Session info: chrome=81.0.4044.92)
Whenever webelement is found but not ready to interact then webdriver will throw element not intractable exception.
1.Mostly it occurs, when element is located in bottom of the page, so it can be accessible by scrolling the page down. You can use Action class to scroll to scroll to that element
WebElement element = driver.findElement(By.id("my-id"));
Actions actions = new Actions(driver);
actions.moveToElement(element);
## actions.click();
actions.perform();
2. Sometimes we need to wait few seconds to access the web element, in such situations we can add wait statements.
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))

Not able to click Checkbox Element using Python Selenium integration

I am trying to iterate over pages having a program List and then I have to select checkbox defined in an image below in order to get the run length of a loop on-page.
But when I am trying to navigate over pages via the next button it will stop clicking on checkboxes and throws me below error.
I have tried with xpath,css selector and id method But all get failed.
DOM element SS along with checkbox highlighted
Line of Code Used-
CheckBoxclick = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#workflow_table > thead > tr > th.first.checkbox-column.checkbox > input"))).click()
Error:-
File "D:/Vipul Garg Backup/XXXX/TestingPardotExportProgramsData.py", line 74, in <module>
ProgramsPathlist = getDataForPrograms(RecordsonOnePage,totalnofpages)
File "D:/Vipul Garg Backup/XXXX/TestingPardotExportProgramsData.py", line 63, in getDataForPrograms
RecordsonOnePage = getrecordsoNpage()
File "D:/Vipul Garg Backup/XXXX/TestingPardotExportProgramsData.py", line 42, in getrecordsoNpage
CheckBoxclick = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#workflow_table > thead > tr > th.first.checkbox-column.checkbox > input"))).click()
File "C:\Users\Vipul.Garg\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\webelement.py", line 80, in click
self._execute(Command.CLICK_ELEMENT)
File "C:\Users\Vipul.Garg\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\webelement.py", line 633, in _execute
return self._parent.execute(command, params)
File "C:\Users\Vipul.Garg\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\Vipul.Garg\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
(Session info: chrome=80.0.3987.122)
But Above Line of Code is Working Intermetantly and throwing error as above.
Any suggestions for this line of code replacement as why I am getting such inconsistency.
You are using ID of the Table and checkbox is inside that table, so you need to pass locator of the check box.
As there is no id defined for the checkbox, so using xpath to reach the locator like - //input[#type='checkbox']

Selenium cannot get iframe

I am trying to retrieve the Job Description and Job Requirements from this link:
https://www.jobsbank.gov.sg/ICMSPortal/portlets/JobBankHandler/SearchDetail.do?id=JOB-2016-0008238
using selenium. This is my code:
driver = webdriver.Firefox()
url = "https://www.jobsbank.gov.sg/ICMSPortal/portlets/JobBankHandler/SearchDetail.do?id=JOB-2016-0008238"
driver.get(url)
iframes = driver.find_elements_by_xpath('//*[#id="divMainJobDescription"]')
print len(iframes)
driver.switch_to_frame(iframes)
print driver.page_source
I get the following error:
Traceback (most recent call last): File "D:\scraper.py", line 79, in
main() File "D:\Abigail MTI Projects\Singapore Skills\JobsBankScraper\jobsbank14012016_abi.py", line 74, in main
driver.switch_to_frame(iframes) File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py",
line 537, in switch_to_frame
self._switch_to.frame(frame_reference) File "C:\Python27\lib\site-packages\selenium\webdriver\remote\switch_to.py",
line 67, in frame
self._driver.execute(Command.SWITCH_TO_FRAME, {'id': frame_reference}) File
"C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py",
line 201, in execute
self.error_handler.check_response(response) File "C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py",
line 181, in check_response
raise exception_class(message, screen, stacktrace) NoSuchFrameException: Message: Unable to locate frame: [object Object]
Stacktrace:
at FirefoxDriver.prototype.switchToFrame (file:///c:/users/mti_wl~1/appdata/local/temp/tmpwelh3x/extensions/fxdriver#googlecode.com/components/driver-component.js:10745)
at DelayedCommand.prototype.executeInternal_/h (file:///c:/users/mti_wl~1/appdata/local/temp/tmpwelh3x/extensions/fxdriver#googlecode.com/components/command-processor.js:12551)
at DelayedCommand.prototype.executeInternal_ (file:///c:/users/mti_wl~1/appdata/local/temp/tmpwelh3x/extensions/fxdriver#googlecode.com/components/command-processor.js:12556)
at DelayedCommand.prototype.execute/< (file:///c:/users/mti_wl~1/appdata/local/temp/tmpwelh3x/extensions/fxdriver#googlecode.com/components/command-processor.js:12498)
iframes is list, you need to switch to a single frame.
driver.find_elements return list while driver.find_element return single web element (note the 's' in element/s).
In addition, divMainJobDescription is not iframe, I believe you are looking for frameJobDescription
iframe = driver.find_element_by_id("frameJobDescription")
You need to target the iframe, switch to that frame, and then you can start identifying other elements, like divs, which exist inside that frame. You need to specify the iframe tag itself and not an element inside the iframe.
So, instead of targeting a div immediately inside the frame like
iframes = driver.find_elements_by_xpath('//*[#id="divMainJobDescription"]')
target the iframe tag, then switch. (You can use the singular find_element_by_xpath if you want only one iframe.)
iframe = driver.find_element_by_xpath('//iframe[#id="frameJobDescription"]')
driver.switch_to_frame(iframe)
job_description = driver.find_element_by_xpath('//*[#id="divMainJobDescription"]')
Bonus: You can use other methods to target the iframe, such as finding the element by ID instead of writing the xpath, if you are only looking at IDs.
iframe = driver.find_element_by_id('frameJobDescription')
If you need to get details in BOTH iframes during your script, you will need to take turns switching between frames.

Categories

Resources