Here is the element:
<label title="Place Order" style="cursor: pointer" onclick="AjaxPageLoad(fno, 'FNOOrder');">Place Order<div></div></label>
I am trying to click on this but need to use the #onclick as the main differentiator. I read the other similar questions but can't seem to get this to work:
driver.find_element_by_xpath("//a[contains(#onclick,'fno')]").click()
driver.find_element_by_xpath("//a[contains(#onclick,'FNOOrder')]").click()
Error I get:
ElementNotInteractableException: Message: Element <a id="lnkFNO" class="active" href="javascript:void(0)"> could not be scrolled into view
But the element is visible so I assume that the xpath must be wrong.
As per the HTML you have shared to click on the desired element using the onclick event you have to induce WebDriverWait and you can use the follwing solution:
xpath using onclick:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[#onclick=\"AjaxPageLoad(fno, 'FNOOrder');\"]"))).click()
xpath using onclick and title:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[#title='Place Order'][#onclick=\"AjaxPageLoad(fno, 'FNOOrder');\"]"))).click()
xpath using onclick, title and innerHTML:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[#title='Place Order'][#onclick=\"AjaxPageLoad(fno, 'FNOOrder');\"][contains(.,'Place Order')]"))).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
Try to use css selector, if you are familiar with web development, it should be easier.
driver.find_element_by_css_selector("label[onclick*=fno]").click()
Above code will select label with onclick argument contains 'fno' string. Here you can find all selectors: https://www.w3schools.com/cssref/css_selectors.asp
Related
I was making a webscraper to get gpu stocks from https://www.nvidia.com/en-us/shop/geforce/?page=1&limit=9&locale=en-us to get my hands on a 30 series card, I am using python with bs4 and selenium for this.
I want to load more shopping items, on the website it has this load more button. So I grabbed its class and made it so selenium clicks it:
driver.find_element_by_class_name("buy-link").click()
but it says that the element in non interactiable, HTML for the button
The exact error it gives me is:
Message: element click intercepted: Element <span class="extra_style buy-link" data-color="#76b900" data-secondary-color="#fff" style="visibility: visible; cursor: pointer;" data-mpn-code="NVGFT070">...</span> is not clickable at point (657, 594). Other element would receive the click: <div class="popBg" id="nv-buy-now-model" style="display: block;">...</div>
I don't know much HTML, how can I achieve clicking this button
The LOAD MORE element is a Angular element so to click on it you need 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://www.nvidia.com/en-us/shop/geforce/?page=1&limit=9&locale=en-us")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#cookiePolicy-btn-close>span"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.buy-link.load-more-btn[value='LOAD MORE']"))).click()
Using XPATH:
driver.get("https://www.nvidia.com/en-us/shop/geforce/?page=1&limit=9&locale=en-us")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#id='cookiePolicy-btn-close']/span"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#class='buy-link load-more-btn' and #value='LOAD MORE']"))).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:
The problem is that there are some 20 elements on that page that match your first locator, .find_element_by_class_name("buy-link"). In this case, if you make your locator more specific, you can isolate it down to just the "LOAD MORE" INPUT button.
Try this instead
driver.find_element_by_css_selector("input.buy-link").click()
It's generally a good practice to add a wait unless you are sure you won't ever need it.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, "//span[text()='CLOSE']")).click()
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.buy-link")).click()
See the docs for more info and details.
Here is the HTML of the button I am trying to locate, it appears to me as an angular component:
<tab-button class="tab-button _ngcontent-jne-2 _nghost-jne-3" focusitem="" role="tab" aria-selected="false" tabindex="-1" aria-disabled="false" aria-label="Offline Reporting">
<!---->
<div class="content displayed-value _ngcontent-jne-3">Offline Reporting</div>
<!---->
<material-ripple class="_ngcontent-jne-3">
<div class="__acx-ripple" style="top: -103px; left: -45px; transform: translate(17px, -1px) scale(0.88156);"></div>
<div class="__acx-ripple" style="top: -101px; left: -62px; transform: translate(34px, -3px) scale(0.88156);"></div>
</material-ripple>
</tab-button>
Note that I want to locate tab-button which has aria-label = Offline Reporting. Here's what all I have tried:
element = driver.find_element_by_xpath("//tab-button[#aria-label='Offline Reporting']")
element = driver.find_element_by_tag("tab-button")
element = driver.find_element_by_tag_name("tab-button")
element = driver.find_element_by_css_selector("tab-button")
None of the above actually worked. Can you point out the right way to do the same? I have to locate the tab-button (Out of many) which has aria-label as Offline Reporting
Quick Edit
Note that I am using Selenium Web Driver for the same purpose and the page I am trying to load is an Angular page. From my understanding, the content is dynamically rendered here and so even though I can see it in element inspector, It's not getting located with find_element function.
Here is the snapshot of the same:
Note that I have tried everything that's mentioned in the current answers... that is waiting for the page to load completely and even if it loads completely I tried a delay of 50s as shown below:
WebDriverWait(driver, 50).until(EC.visibility_of_element_located((By.XPATH, "//tab-button[contains(#class, 'tab-button') and #aria-label='Offline Reporting']")))
But this ended up in timeout as well. The point I am trying to raise through these lines is that this is a dynamically rendered page and so to handle it there's some other middleware mechanicsm needed like scrapy-selenium
Try to wait for button to be become visible and clickable:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//tab-button[#aria-label='Offline Reporting']")))
button.click()
To locate the element with text as Offline Reporting you can use either of the following Locator Strategies:
Using css_selector:
element = driver.find_element_by_css_selector("tab-button.tab-button[aria-label='Offline Reporting']")
Using xpath:
element = driver.find_element_by_xpath("//tab-button[contains(#class, 'tab-button') and #aria-label='Offline Reporting']")
As the element is an Angular element, ideally to locate the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "tab-button.tab-button[aria-label='Offline Reporting']")))
Using XPATH:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//tab-button[contains(#class, 'tab-button') and #aria-label='Offline Reporting']")))
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
So I just started using Selenium for Python and I am trying to click on a button element that is buried into a few div elements; I've tried so many things but nothing works. Everything in the code works besides the last part which is waiting for the button to be clickable and then clicking it. I would greatly appreciate some help here, thanks. :)
HTML:
Code trials:
Error stacktrace:
To click on **Maybe Later** button.
Induce WebDriverWait() and element_to_be_clickable() and following XPATH or CSS Selector.
XPATH:
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//div[#class='modal-footer']//button[#Class='btn btn-danger x' and text()='Maybe Later']"))).click()
CSS Selector:
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"div.modal-footer button.btn.btn-danger.x[style='danger']"))).click()
You need to import following libraries.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
css selectors will become your best friend,
you should always look to add as many attributes as possible
maybe_later_css = 'button[class="btn btn-danger"]'
# type str, '<tag-name>[<attribute-name> = <attribute-value>]'
driver.find_element_by_css_selector(maybe_later_css).click()
follow this format for all elements, its superior and works as expected every time
the only complication is when there exists multiple buttons with them same class name, in which case you should find a different attribute to fill the [] brackets
The element with text as Maybe Later is within a Modal Dialog Box so to locate and click() on the element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.modal-footer#eFooter button.btn.btn-danger.x[style='danger']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='modal-footer' and #id='eFooter']//button[#class='btn btn-danger x' and #style='danger']"))).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
I try to click on html a tag with selenium but I get an error.
How can I get selenium to click on such tag?
I've tried this code but I get an error:
driver.find_element_by_id("btnCreateJE").click()
HTML code:
<a id="btnCreateJE" data-permission="true" onclick="NewManualJE()" href="#" class="btn waves-effect waves-light"> New </a>
Python selenium code:
driver.find_element_by_id("btnCreateJE").click()
I get that error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="btnCreateJE"]"}
(Session info: chrome=75.0.3770.142)
Make sure that the element doesn't belong to the iframe, if this is the case - you will need to switch_to_frame first
Make sure that the element doesn't belong to the Shadow DOM, if this is the case - you will have to find the relevant ShadowRoot and locate your element relatively
It might be the case the link is not immediately present in DOM, i.e. it's being added later as a result of an AJAX call. If this is the case - consider adding Explicit Wait like:
WebDriverWait(driver, 10).until(expected_conditions.presence_of_element_located((By.ID, "btnCreateJE"))).click()
The desired element is a JavaScript enabled element so to click() on the element you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using PARTIAL_LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, "New"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.btn.waves-effect.waves-light#btnCreateJE[onclick^='NewManualJE']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='btn waves-effect waves-light' and #id='btnCreateJE'][starts-with(#onclick, 'NewManualJE')]"))).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
I want to locate (and click) the "Reoni" element, but I do not know what function to use it for
I tried with
driver.find_element_by_class_name("oe_menu_leaf")
and
driver.find_element_by_class_name("oe_menu_text")
but then selenium raise an error element cant be located,
and I tried
driver.find_element_by_link_text("Reoni")
This is the element I want to locate:
<a href="/web#menu_id=86&action=99" class="oe_menu_leaf" data-menu="86" data-action-model="ir.actions.act_window" data-action-id="99">
<span class="oe_menu_text">
Reoni
</span>
</a>
and full html:
If I was not clear enough or if you needed my code, please let me know.
As the desired element is a dynamic element you need to induce WebDriverWait for the desired element to be clickable and you can use either of the following solutions:
Using CSS_SELECTOR:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.oe_menu_leaf[href*='/web#menu_id=']>span.oe_menu_text"))).click()
Using XPATH and text():
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='oe_menu_leaf' and starts-with(#href,'/web#menu_id=')]/span[#class='oe_menu_text' and text()='Reoni']"))).click()
Using XPATH and normalize-space():
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='oe_menu_leaf' and contains(#href,'/web#menu_id=')]/span[#class='oe_menu_text' and normalize-space()='Reoni']"))).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
Reference
You can find a relevant detailed discussion in:
Selenium “selenium.common.exceptions.NoSuchElementException” when using Chrome
Try something like this:
Clicking the button
From Chrome :
Right click "inspect" on the item you are trying to find the xpath.
Right click on the highlighted area on the console.
Go to Copy xpath
selectElem=browser.find_element_by_xpath('x-path-here').click()
Reading Values Only
from bs4 import BeautifulSoup
innerHTML = browser.execute_script("return document.body.innerHTML")
soup = BeautifulSoup(str(innerHTML.encode('utf-8').strip()), 'lxml')
value = soup.find('span', attrs={'class':'fxst-calendarpro fxst-table-s1'}).text