Python selenium webdriver locate and click links - python

I have a table column with four links in the same cell:
<td>
<a href="", onclick=showPricing('1234567','P', 'xyz123456', )>pdf,</a>
<a href="", onclick=showPricing('1234567','C', 'xyz123456', )>csv,</a>
<a href="", onclick=showPricing('1234567','X', 'xyz123456', )>xls,</a>
<a href="", onclick=showPricing('1234567','XP', 'xyz123456', )>xlsp</a>
</td>
I want to click the fourth one link text "xlsp", but not able to.
What I tried:
1) driver.find_element_by_xpath('//a[contains(#onclick, "xyz123456")]').click()
this of course clicks the first one: pdf
2) driver.find_element_by_xpath('//a[contains(#onclick, "xyz123456")][contains(text(), "xlsp")]').click()
this picks the fourth one, but error out with
"....errorElement could not be scrolled into view"
3) driver.find_elements_by_xpath('//a[contains(#onclick, "xyz123456")]')[3].click()
this returns the same error as 2)
Any suggestions are appreciated.

To click the fourth forth link with text as xlsp you can use either of the following solutions:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "td a[onclick*='XP']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[contains(#onclick,'XP') and contains(.,'xlsp')]"))).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 tested multiple options, including #DebanjanB's suggestion, and think this is the most reliable solution:
driver.execute_script(dr.find_element_by_xpath('//a[contains(#onclick, "xyz123456")][contains(#onclick, "XP")]').get_attribute("onclick"))

Related

Clicking a span element in a class with python selenium

I am trying to click into the Over/Under Section on this Website:
https://www.oddsportal.com/soccer/chile/primera-division/curico-unido-o-higgins-CtsLggl6/
The HTML is:
<li class=" active" style="display: block;"><span class="topleft_corner"></span><span class="topright_corner"></span><strong><span>Over/Under</span></strong></li>
I have tried the following:
overunder=browser.find_element_by_link_text('Over/Under')
overunder=wait(browser, 5).until(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(), 'Over/Under']")))
overunder=browser.findElement(By.xpath("//span[contains(text(), 'Over/Under']"))
All of these followed by overunder.click()
However all result in a NosuchElementException.
How can I click this item?
I am trying to access and scrape the Over/Under Websites behind this section.
I copied the full xpath and this worked for me:
browser.find_element_by_xpath("/html/body/div[1]/div/div[2]/div[6]/div[1]/div/div[1]/div[2]/div[1]/div[5]/div[1]/ul/li[5]/a").click()
When I checked the page_source of the link you provided using selenium, this is what I get for area you're looking for:
<li class="" style="display: block;"><a onmousedown="uid(5)._onClick();return false;" title="Over/Under" href=""><span>O/U</span></a></li>
I used
browser.find_element_by_css_selector("a[title='Over/Under']").click()
which worked for me.
Instead of the element with text Over/Under, I see the element with text O/U
To click on the element with text as save you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element(By.CSS_SELECTOR, "a[title='Over/Under'] > span").click()
Using xpath:
driver.find_element(By.XPATH, "//a[#title='Over/Under']/span[text()='O/U']").click()
Ideally, to click on 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:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[title='Over/Under'] > span"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#title='Over/Under']/span[text()='O/U']"))).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:

How to locate tag-button (Angular Component) in Selenium?

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

Cannot click tag <a> with <i class> selenium python

I want to make a simple attendance automation with python for my college, I make this for ease, because this took so many button to click but, I cannot click the tag <a> with tag <i> inside it.
<a href="http://siakad.polinema.ac.id/mahasiswa/tr_absensi/add"
class="btn btn-sm green-meadow btn-add-data" id="btn-add-wizard">
<i class="fa fa-plus"></i> Absen</a>
I use this wait function, and still not directed into that link. It shows nothing on result. Process finished with exit code 0
wait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,"//a[contains(#href, ""'http://siakad.polinema.ac.id/mahasiswa/tr_absensi/add')]"))).click()
I tried using ID and LINK_TEXT and still showing Process finished with exit code 0.
Thank you, apologize for my english. Enghlish is not my main language. If you need more information about my question, please let me know.
To click on the element with text as Absen 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, "a.btn.btn-sm.green-meadow.btn-add-data#btn-add-wizard[href$='id/mahasiswa/tr_absensi/add']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='btn btn-sm green-meadow btn-add-data' and #id='btn-add-wizard'][contains(#href, 'id/mahasiswa/tr_absensi/add')]"))).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 need to acces to the next page with selenium or Beautiful Soup

I think I have already tried all the .click() .submit... all different kind of things but it doesn't do anything
What appears when I try to acces to the next page is the following, as as isn't a button or appears a web site I don't know what to do; the only thing that changes in all the pages is the number in the value, that here appears a 3
<ul class="pagination">
<li><span onclick="document.lisarq.pagina.value=3; document.lisarq.submit(); " onmouseover="this.style.cursor='pointer'" style="cursor: pointer;">3</span></li>
</ul>
The only thing that I want to do is access to the next page in this case would be the 4
Thanks!
As the element is JavaScript enabled element, to click() and access Page 4 you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following solutions:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "ul.pagination>li>span[onclick*='4']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[#class='pagination']/li/span[contains(#onclick, '4') and text()='4']"))).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

How to use the onclick event as a selector in webdriver?

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

Categories