Unable to locate <a> element using Selenium - python

I'm a newbie with Selenium trying a project out and I'm trying to click on a link on a page but Selenium says it could not find the element. Here is the inspected element:
<a data-action="renditions--schedule-item-list#showAvailableItems" class="available-items-btn">
<i class="icon-bullhorn"></i>
Available Items
</a>
Here is what I've tried:
driver.find_element_by_xpath('//a[text()="Available Items"]').click()
and
driver.find_element_by_class_name("a.available-items-btn").click()
Any idea what's wrong?

Sometimes finding by exact text match doesn't always work. Try this:
driver.find_element_by_xpath("//a[contains(text(), 'Available Items')]")
Or, try your second attempt again but remove the a.
driver.find_element_by_class_name("available-items-btn").click()

Related

Trying to click entry buttons on gleam using selenium but am having trouble identifying the element

Here is the inspect result for the button that says +5 per day
>span class="text user-links entry-method-title ng-scope ng-binding" ng-include="::'views/entry-text/'+entry_method.entry_type+'.html'">
Click For a Daily Bonus Entry"
</span>
<div class="entry-method bonus template" data-remove-popovers="" id="em6129519" ng-class="{expanded: entryState.expanded == entry_method, template: entry_method.template, 'completed-entry-method': !canEnter(entry_method) && isEntered(entry_method)}" ng-repeat="entry_method in ::entry_methods">
here is the HTML given information when I inspect the link/button, I have tried to use XPath, CSS, link text, and class name and it keeps giving me an error saying it cannot identify the element. Does anyone have a suggestion for how to identify this, it is on gleam.io for a giveaway I'm trying to automate this so i don't have to log in and press this everyday. This is my first ever web interfacing project with python.
Here is my most recent try
driver.maximize_window()
time.sleep(10)
driver.execute_script("window.scrollTo(0, 1440)")
time.sleep(10)
button2 = driver.find_element_by_class_name("text user-links entry-method-title ng-scope ng-binding")
button2.click()
Similar to a previous issue, Selenium find_element_by_class_name and find_element_by_css_selector not working, you can't have spaces in your class name when using driver.find_element_by_class_name. Instead, find the element via css_selector and replace each space with a dot.
driver.find_element_by_css_selector("span.text.user-links.entry-method-title.ng-scope.ng-binding")
That'll fix what you have above, but keep in mind there are other ways to make selenium actions more reliable (eg. WebDriverWait, etc). And there may be a cleaner selector to use than the one above.
I believe the element you want to access is contained within an "iframe", thus you must first switch to iframe before you can access it using selectors.
driver.switch_to.frame(x.find_element_by_xpath("PUT IFRAME XPATH HERE"))

Selecting dynamic element using selenium and python

Could someone please tell me how can I select a dynamic element using selenium?
I would like to select the "limit-order" element.
<div class="tab-control" id="uniqName_0_85" widgetid="uniqName_0_85">
<span data-tab="market-order" class="tab-item tab-active">Market</span>
<span data-tab="limit-order" class="tab-item">Limit</span>
<span data-tab="stop-order" class="tab-item">Stop</span>
<span data-tab="stop_limit-order" class="tab-item">Stop Limit</span>
</div>
I tried this but no luck:
btn_limit_name_xpath = '//div[contains(#class,"tab-control")]/span[2]'
btn_limit = browser.find_element_by_xpath(btn_limit_name_xpath)
btn_limit.click()
What sometimes does the job for me is copy the full xpath instead of the shorter one.
If that doesn't work either, you could try and check this out.
They show you how you can use an xpath to find a specific piece of text and select the object in that way. So in your case you could try and find it by searching for 'limit'.

Selenium XPath is not working, the console cant find the element

I know the basics of python and I am trying out Selenium. This page I am on is my schoolwork website. I want to select every single element in the timeline of my homework. I tried to select the whole timeline with XPath or even just one specific homework(elem) but both have this error code:
selenium.common.exceptions.NoSuchElementException: Message: no such
element: Unable to locate element:
{"method":"xpath","selector":"//*[#id="jwdd3b016b_acnt"]/div[3]/ul/li[3]"}
(Session info: chrome=81.0.4044.122)
This is the code:
from selenium import webdriver
driver = webdriver.Chrome('C:\\Users\\tomas\\Downloads\\chromedriver_win32\\chromedriver')
driver.get('https://glnt.edupage.org/timeline/')
#then I log in but that's not important
important_stuff = driver.find_element_by_xpath('//*[#id="jwdd3b016b_acnt"]/div[3]/ul/li[3]')
I have no idea what to do. I was under the impression that when u use XPath the code should always work. Am I wrong? (not always I mean, but when the code is correct)
Edit: sorry I forgot here is the HTML of the element:
<li class="hwItem m04 d5" data-typ="timeline" data-homeworkid="timeline:2031705" data-date="2020-04-24" data-timelineid="2031705">
That should do it:
<div class="edubarMainNoSkin">
<div id="jwdd3b016b_acnt" class="hwMainListMain">
<div class="hwListElem">
<ul class="hwList timelineMode ">
I couldn't say much without seen more of the HTML.
//*[#id="jwdd3b016b_acnt"]/div[3]/ul/li[3]
id part may not be constant.
It might be inside of an iframe, so you have to switch into it.
Due to browser rendering, deepness of the div might be changed.(div[3] would be changed)
First find the correct element using developer tools.
Then while executing using webdriver put a break point and check via developer tools.

How do I find these particular elements in a webpage, with selenium using chromedriver?

I have a website that I'm trying to automate but I can't find a particular link with selenium to click on. It looks like a link on the website, but when I use the chrome "inspect" function, it looks like it might be a button (???). I've tried copying the Xpath, but that doesn't work.
Here is the HTML behind the link
<button ng-bind-html="::ListingCtrl.copy.planListing.noPreference" track="No Preference" ng-click="::ListingCtrl.enterNoPreference()" class="link ally-focus-within">No Preference</button>
The Xpath for it is
//*[#id="mainContent"]/div/div/div/div[2]/ul/li[1]/h2/button
The text of the link is "No Preference", so also tried the following
elem_NoPreference = browser.find_element_by_xpath('//#track=\'No Preference\'')
But I'm not sure if my quote escape characters are correct.
I also unsuccessfully tried the following
elem_NoPreference = browser.find_element_by_link_text('No Preference') <br>
elem_NoPreference = browser.find_element_by_class_name('link ally-focus-within') <br>
elem_NoPreference = browser .find_element_by_css_selector("button[class='link ally-focus-within']
I should mention that the following are unique in the HTML. So, if there is a way to find these using the Xpath, it would be helpful
ListingCtrl.copy.planListing.noPreference
ListingCtrl.enterNoPreference()
track = "No Preference"
I'm at my wits end here. Any help would be appreciated.
Thank you!
If you don't plan to do any I18N / L10N testing you can stick to No Preference text, in this case the selector would be:
//button[text()='No Preference']
other option is basically the same, but instead of text it looks for track HTML attribute:
More information:
XPath Tutorial
XPath Operators & Functions
Xpath cheatsheet
Try with this xpath:
elem_NoPreference = browser.find_element_by_xpath("//button[#track='No Preference']")
or, if you want to select the element by the containing text:
elem_NoPreference = browser.find_element_by_xpath("//button[contains(.,'No Preference')]")

clicking on a link with the same href value using selenium python

I have a html code that has two links but both the links have the same href value, but the onclick and the text are different.
I wasn't sure as to how to access the second link.
I tried using driver.find_element_by_link_text('text'), but I get a no such element found error.
<div id="member">
<"a href="#" onclick="add_member("abc"); return false;">run abc<"/a>
<br>
<"a href="#" onclick="add_member("def"); return false;">run def<"/a>
</div>
There are multiple options to get the desired link.
One option would be to get use find_element_by_xpath() and check onclick attribute value:
link = driver.find_element_by_xpath('//div[#id="member"]/a[contains(#onclick, "add_member(\"def\")")]')
link.click()
Another one would be to simply find both links and get the desired one by index:
div = driver.find_element_by_id('member')
links = div.find_elements_by_tag_name('a')
links[1].click()
Which option to choose depends on the whole HTML content. Hope at least one of two suggested solutions solves the issue.

Categories