I am attempting to locate a user name field that does not have an ID or other locator that I can easily find using Selenium Web Driver.
Using Chrome's Inspect Element, the HTML for this object is as follows
<div aria-hidden="true" style="cursor:text" data-bind="text: hintText, css: hintCss" class="placeholder">someone#example.com</div>
What would be the best way to locate this page object?
Thanks
Either of these should work (if it is the first div-element of this class type)
driver.find_element_by_class_name('placeholder')
driver.find_element_by_css_selector('div.placeholder')
driver.find_element_by_xpath("//div[#class='placeholder']")
If there are more elements which match use the find_elements version of the methods and use the index of the returned list the get the element you need.
To click() the User Name field you can use either of the following line of code :
Using class and text attributes :
driver.findElement(By.xpath("//div[#class='placeholder' and contains(text(),'someone#example.com')]"));
Using class and aria-hidden attributes :
driver.findElement(By.xpath("//div[#class='placeholder' and #aria-hidden='true']"));
First find out is your element is inside different frame. Find the iframe, first switch to that, after which you will able to locate your user desired object by using any method like find_elemet_by_class_name or find_element_by_css_selector or by xpath.
For switching to frame try below code:
driver.switch_to.frame(driver.find_element_by_id("ID_OF_YOUR_FRAME"))
You can take the reference from this link code also for searching elements:
"https://github.com/PrajinkyaPimpalghare/TimeSheet-Automation/blob/master/time_sheet_automation.py" Refer from line 94 to 108 for accessing elements in different way and also in different frame.
Related
I'm trying to get text using Selenium WebDriver and here is my code. Please note that I don't want to use XPath, because in my case the ID gets changed on every relaunch of the web page.
My code:
driver.find_element_by_class_name("05uR6d").text
HTML:
<div class="O5uR6d">to fasten stuff</div>
Error:
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified (Session info: chrome=88.0.4324.150)
Error is specific to the line of code I mentioned above.
How can I fix this?
Use this xpath:
driver.find_element_by_xpath("//div[contains(text(),'to fasten stuff')]")
Or this CSS:
driver.find_element_by_css_selector(".O5uR6d")
If both won't work, improve your question by adding more data of HTML you are looking at.
It can be done using multiple ways let me try to explain most of them.
Get element by class name.
this is the most easiest solution to get any element by class name you can simply do is:
driver.find_element_by_class_selector('foo');
Get Element by xpath
This is a bit tricky one, you can apply xpath either the class name, title, id or whatever remains same. it also works even if there's a text inside your div. For example:
driver.find_element_by_xpath("//tagname[#attribute='value']")
or in your case:
driver.find_element_by_xpath("//div['class='O5uR6d']")
or you can do something like #vitaliis said
driver.find_element_by_xpath("//div[contains(text(),'to fasten stuff')]")
You can read more about xpath and how to find it on this link
Get Elements by ID:
You can also get the element from id if there's any that's static:
driver.find_element_by_id('baz')
Get Elements by Name:
Get Elements by name using the following syntax:
driver.find_element_by_name('bazz')
Using CSS Selectors:
You can also use the css selectors to find the elements. Consider a following tag that has some attributes:
<p class="content">Site content goes here.</p>
You can get this element by:
driver.find_element_by_css_selector('p.content')
You can read more about it over here
I am coding a python web automation selenium script.
In the script, I use driver.find_element_by_xpath('xpath') to find elements on Binary.com. This means I would have to preload Binary.com and copy xpaths of the elements I need to find. For most elements the method works but for a few I realised that the Xpath is unique to each login.
For example, if I login in now and try to copy the xpath of a certain element it will be //*[#id="tp1602844250562"] but if the page is reloaded or I try to login on a different window the xpath would have then changed to //*[#id="tp1602844157070"]. Please note they are not the same id numbers. This means I cannot use one xpath on a separate page login
The desired element has an HTML code:
<input type="text" class="time hasTimepicker" tab-index="-1" value="00:00" readonly="" id="tp1602844157070">
Refer to the supplied image for clear html code
You can try below with class instead of id as the id is getting pulled from DB i guess-
//div[#class='date-time']//input[contains(#class,'time')]
Why don't you use the class instead of the id? Try this xpath:
driver.find_element_by_xpath('//input[#class = "time hasTimepicker"]')
Try changing your xpath expression to
//input[starts-with(#id,"tp")]
or, if it's not always input
//*[starts-with(#id,"tp")]
To find the input element with that class use.
driver.find_element_by_css_selector("input.time.hasTimepicker")
I have a xpath as:
//*[#id="jobs-search-box-keyword-id-ember968"]
The number 968 constantly keeps on changing after every reload.
Rest of the string remains constant.
How to I find the constantly changing xpath?
You can use partial id with contains()
//*[contains(#id, "jobs-search-box-keyword-id-ember")]
You can try using starts-with below,
//*[starts-with(#id,'jobs-search-box-keyword-id-ember')]
The details provided is insufficient to to provide the accurate result. Still you can follow the below code references
In //*[#id="jobs-search-box-keyword-id-ember968"] the last number 968 keeps changing. but if you make this like //*[starts-with(#id,'jobs-search-box-keyword-id-ember')] then there might be possibility that you can have more then one element with the same partial is i.e. jobs-search-box-keyword-id-ember in this case it will locate on 1st matching element. that may not be your expected one
Use the tag name lets say element is an input tag whose id is jobs-search-box-keyword-id-ember968
Xpath - //input[starts-with(#id,'jobs-search-box-keyword-id-ember')]
CSS - input[id^='jobs-search-box-keyword-id-ember']
Use the relevant parent element to make this more specific. e.g the element is in parent tag <div class="container">
Xpath- //div[#class='container']//input[starts-with(#id,'jobs-search-box-keyword-id-ember')]
CSS - div.container input[id^='jobs-search-box-keyword-id-ember']
This worked for me:
Locator:
JOBS_SEARCH_BOX_XPATH = "//*[contains(#id,'jobs-search-box-keyword-id-ember')]"
Code:
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, JOBS_SEARCH_BOX_XPATH)))
.send_keys("SDET")
I am using the following code using Python 3.6 and selenium:
element = driver.find_element_by_class_name("first_result_price")
print(element)
on the website it is like this
`website: span class="first_result_price">712
however if I print element I get a completely different number?
Any suggestions?
many thanks!!
"element" is a type of object called WebElement that Selenium adds. If you want to find the text inside that element, you have to say
element.text
Which should return what you're looking for, '712', albeit in string form.
In the case that I want the first use of class so I don't have to guess the find_elements_by_xpath(), what are my options for this? The goal is to write less code, assuring any changes to the source I am scraping can be fixed easily. Is it possible to essentially
find_elements_by_css_selector('source[1]')
This code does not work as is though.
I am using selenium with Python and will likely be using phantomJS as the webdriver (Firefox for testing).
In CSS Selectors, square brackets select attributes, so your sample code is trying to select the 'source' type element with an attribute named 1, eg
<source 1="your_element" />
Whereas I gather you're trying to find the first in a list that looks like this:
<source>Blah</source>
<source>Rah</source>
If you just want the first matching element, you can use the singular form:
element = find_element_by_css_selector("source")
The form you were using returns a list, so you're also able to get the n-1th element to find the nth instance on the page (Lists index from 0):
element = find_elements_by_css_selector("source")[0]
Finally, if you want your CSS selectors to be completely explicit in which element they're finding, you can use the nth-of-type selector:
element = find_element_by_css_selector("source:nth-of-type(1)")
You might find some other helpful information at this blog post from Sauce Labs to help you write flexible selectors to replace your XPath.