I am having an problem with clicking an menu item that has an link with an href with selenium web drive.
<a class="a-link-normal" href="javascript:;">Fiction</a>
Here is my code:
driver.find_element_by_xpath('//*[#id="div-fiction"]/span/a').click()
This only seem to hover over the linked name and highlight it but does not trigger the javascript. I tried reading all the other solutions but it all lead to just using the click() method. Does anyone know what is wrong or a different approach to this.
The desired element seems to be a JavaScript enabled element so you need to induce WebDriverWait for the desired element to be clickable and you can use either of the following solutions:
LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Fiction"))).click()
XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='a-link-normal' and contains(.,'Fiction')]"))).click()
You may try this:
driver.execute_script("arguments[0].click();", webelement to click)
Related
does anyone know how I can get past this pop-up using selenium? When I log into Facebook regularly it doesn't come up but for some reason unknown to me, it keeps firing up when I run my script.
cookie_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[id='u_0_j_I5']"))).click()
This is the script I'm trying to use to get rid of it but it isn't working
The css selector that you are using:
button[id='u_0_j_I5']
looks dynamic and brittle in nature. What that means is, every time you refresh a page you would see a different id generated from the backend.
I would suggest you use a locator which should be reliable and not too easy to break.
A CSS:
input[data-cookiebanner='accept_button']
or XPath
//input[#data-cookiebanner='accept_button']
but you should be mindful of the uniqueness of the locator.
Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath/css and see, if your desired element is getting highlighted with 1/1 matching node.
If they are unique, then you can use the below code:
cookie_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[data-cookiebanner='accept_button']")))
cookie_button.click()
Update:
Use the below XPath:
//button[contains(text(),'Allow All Cookies')]
and click it like this:
cookie_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Allow All Cookies')]")))
cookie_button.click()
I'm using Selenium in a Python script to query NASA's Small Body Database for the location of asteroids. I've been working with a Python shell to check that my commands are getting the results I want, but I'm having a consistent issue with the "submit" method.
The page I'm working on is https://ssd.jpl.nasa.gov/sbwobs.cgi. All I want to do is have Selenium click on the "change" link next to "Observation Time," fill in a field on the page that opens, and then click the resulting "Use Specified Time" button.
I've set up a Selenium WebDriver object named "browser", and then the first command I send is:
browser.find_element_by_css_selector("a[href*='time']").click()
Which works and sends me to my target page, which is https://ssd.jpl.nasa.gov/sbwobs.cgi?s_time=1#top
I then find the text field and fill it in with:
browser.find_element_by_name('obs_time').send_keys("2021-04-01 01:00")
... last thing I need is to click the "Use Specified Time" button to accept this. I tried with:
browser.find_element_by_name("check_time").click()
.. but this had no response. Then I tried:
browser.find_element_by_name("check_time").submit()
... which seems to work, but takes me back to the previous page without actually changing the time. If I manually click on the button it would work fine.
Selenium is definitely finding the right element, and the submit method is doing something, but it's maybe not sending the info in the text box correctly.
I don't know anywhere near enough about HTML etc to be able to figure this out. Can anyone offer any advice?
You were close enough. Before you set the new Observation Time as 2021-04-01 01:00 you need to clear up the previous input. Ideally, to change the Observation Time you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get('https://ssd.jpl.nasa.gov/sbwobs.cgi')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[href*='time']"))).click()
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='obs_time']")))
element.click()
element.clear()
element.send_keys("2021-04-01 01:00")
driver.find_element_by_css_selector("input[name='check_time']").click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[contains(#href, 'time')]"))).click()
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#name='obs_time']")))
element.click()
element.clear()
element.send_keys("2021-04-01 02:00")
driver.find_element_by_xpath("//input[#name='check_time']").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:
Thanks to #DebanjanB for the comprehensive code that improved all my methods; however, I found that everything worked as expected with his code and mine by switching to Firefox.
Evidently it's some anomaly in Safari's web driver that was causing the issue.
Hi guess, today I struggled with a problem I cant fill card data.https://i.stack.imgur.com/VzN22.png
As I understood it appears cuz of nested html(html in html I'm not good in eng). So what do u supposed to do?
I tried to fill it by id, full xpath, selector etc...
Nothing works.
Some code what I used
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "cardCvc-input"))).send_keys("1234")
data.https://i.stack.imgur.com/VzN22.png
You need to switch to iframe first to access the element.The input element present inside an iframe.
Induce WebDriverWait() and frame_to_be_available_and_switch_to_it() and following css selector.
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[title='payment']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "cardCvc-input"))).send_keys("1234")
To come out from iframe you need to switch to default_content.
driver.switch_to.default_content()
I am pretty new to Python and Selenium, and I have got my script to do what I want so far, but I have this current coding from the website:
<a onclick="realPostBack('ctl00$ctl00$mainContent$ContentPlaceHolder1$ucHub$ucSearchExplorer$dgContents$ctl00$ctl04$lnkContent', ''); return false;" id="ctl00_ctl00_mainContent_ContentPlaceHolder1_ucHub_ucSearchExplorer_dgContents_ctl00_ctl04_lnkContent" class="hub-content-item" actiontype="Secondary" href="javascript:__doPostBack('ctl00$ctl00$mainContent$ContentPlaceHolder1$ucHub$ucSearchExplorer$dgContents$ctl00$ctl04$lnkContent','')"><span>How to Project Wirelessly in Philly</span></a>
and I can't get it to click the link.
I've tried:
driver.find_element_by_text("How to Project Wirelessly in Philly")
and partial text
driver.find_element_by_id("ctl00_ctl00_mainContent_ContentPlaceHolder1_ucHub_ucSearchExplorer_dgContents_ctl00_ctl04_lnkContent")
I've tried by tag but all returning errors. Looking up on here, I've seen stuff with Xpath but I have no clue how to do that, but if someone here does, then a little help with that, or any other simple code that hopefully allows me to click that link. (I know i will have to do .click() to eventually click it, but i cant even find the element yet)
The desired element is a dynamic element, so invoke click() on it you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using CSS_SELECTOR:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.hub-content-item[id*='SearchExplorer'][actiontype='Secondary']>span")))
Using XPATH:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='hub-content-item' and contains(#id,'SearchExplorer')][#actiontype='Secondary']/span[text()='How to Project Wirelessly in Philly']")))
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
Unable to use send_keys() for an iframe. How to select this iframe and which element inside this should be use for send_key()?
and iframe html code
<iframe class="textarea" src="/framework/html/blank.html" style="width: 99%; border-width: 1px; height: 332px;">
#document
<html webdriver="true">
<head>
</head>
<body> … </body>
</html>
</iframe>
How to send the value to description?
One more thing i want to know that this code of frame is not coming when i go for "view page source " in browser?
driver.switch_to.frame(driver.find_element_by_tag_name("iframe")) assuming that driver is a healthy instance of webdriver. To continue with the default content do driver.switch_to.default_content()
EDIT: When you have switched to needed frame, locate your webelement as you always do. I guess (but not sure) in your case this will be a html/body, so
el = driver.find_element_by_xpath('html/body')
should be fine. And perform
el.send_keys('keys_to_send')
EDIT2: Before sending keys you may have to focus on the element (click should do the thing, a child element should appear). Or you can just place the needed text via JS.
driver.execute_script('document.body.innerHTML = "%s"' % text_var)
The Accepted answer works very well for the given question. However I have two reasons for adding one more answer and hope this answer might help someone landing this question with different ask.
Reason 1:
Accepted answer has one way of handling iframes inside a web page. However there are different ways to handle iframes.
By using index position of the frame
By using name of the frame
By using id of the frame
Reason 2:
It uses driver.find_element_by_tag_name("iframe") statement to find iframe element which may not work or return expected iframe web element when there are multiple iframe elements in the same page.
There are many articles out there to explain handling iframes in detail.
http://allselenium.info/handling-iframes-using-selenium-webdriver/
You can switch to the iframe using multiple approaches as per the prevailing condition of the HTML DOM.
If the <iframe> is the only iframe within the DOM Tree you can use the following line of code:
Using TAG_NAME:
driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe"))
Locating the <iframe> element with a unique Locator Strategy:
Using css_selector:
driver.switch_to.frame(driver.find_element(By.CSS_SELECTOR, "iframe.textarea[src='/framework/html/blank.html']"))
Using xpath:
driver.switch_to.frame(driver.find_element(By.XPATH, "//iframe[#class='textarea' and #src='/framework/html/blank.html']"))
Ideally to switch to an <iframe> so you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable.
You can use either of the following Locator Strategies:
Using TAG_NAME (only iframe present):
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.TAG_NAME, "iframe"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe.textarea[src='/framework/html/blank.html']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "element_css_selecor"))).send_keys("character_sequence")
Using XPATH:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#class='textarea' and #src='/framework/html/blank.html']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='TlogBtn']/span[#class='mailicn']/img"))).send_keys("character_sequence")
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
Reference
You can find a couple of relevant discussions in:
Switch to an iframe through Selenium and python
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
selenium in python : NoSuchElementException: Message: no such element: Unable to locate element
In order to handle iframes on a web page you need to switch to the iframes first that are present on the page using this command:
driver.switch_to.frame(frame_id)
This tutorial has a working example of handling iframe using selenium with python which will made you able to get through this issue.