I using selenium i try sed_keys() but element on website have only name and this name is "name".
driver.find_element_by_name("name")
<input type="text" name="name" value="">
Edit:And the items on the page named = "name are two and I want to add a text to the second
Ideally you would find something unique in the DOM above the element you want and use that to build a locator that finds only the element you want. One quick fix would be to use find_elements() (note the plural) and get the second element.
driver.find_elements_by_name("name")[1].send_keys("some text")
^ the 's' will return a collection
^ use array notation to pick the one you want
The problem is if this page changes, e.g. the element order is changed, another matching element is added, etc., then this will start sending text to the wrong element again.
the method which you have given should work , jut try using xpath
your_element = driver.find_element_by_xpath('//*[#name="name"]').click()
Related
I'm using Python and Selenium to fill out a web form. On one of the pages, it has multiple input fields with the same ID. Sometimes it's 1, 2, 3 and 4. Each ticket is different.
Here's my attempt:
how_many_meter_options = len(browser.find_elements_by_xpath("//span[contains(#class,'meterdisplay')]"))
browser.implicitly_wait(30)
print("There are ")
print(how_many_meter_options)
print(" Meter Options")
thecountofmeters = str(how_many_meter_options)
for row_of_meters in thecountofmeters:
browser.find_element_by_xpath("//span[contains(#class,'meterdisplay')]").click()
thelastmeter = browser.find_element_by_id("meteredit-lastreading-display").text
print(thelastmeter)
browser.implicitly_wait(30)
browser.find_element_by_id('meteredit-display').clear()
browser.find_element_by_id('meteredit-display').send_keys(thelastmeter)
browser.implicitly_wait(30)
browser.find_element_by_name('ok').click()
browser.implicitly_wait(30)
This only fills out the first input field. I need it to do all.
Here's the html
<input rt-autofocus="" type="number" id="meteredit-display" name="display" data-ng-model="meter.MeterDisplay" min="0" data-ng-disabled="!canEditMeter()" class="ng-pristine ng-valid ng-valid-number ng-valid-min ng-valid-pattern">
Here's my attempt:
The function find_element_by_id() will only find the first element with a matching id that you put in the arguments. To my knowledge there is no function to find multiple using just the id as an argument, however you might be able to use find_elements_by_xpath("//input[id='meteredit-display']") which will return a group of elements you can iterate through and apply your commands on.
Something like this:
input_elements = browser.find_elements_by_xpath("//input[id='meteredit-display']")
for element in input_elements:
element.clear()
element.send_keys(thelastmeter)
Let me know if you try this and how it works.
Edit: Also I should add that calling browser.implictly_wait() multiple times does nothing. The functions tells the webdriver to wait up to the specified amount of time when trying to find something before it moves on. It is something that just needs to be set once and then you don't have to call it again unless you want to change the amount of time that is waited.
Like Nathan Roberts suggested above, you can look for the xpath, however, having multiple elements with the same id is not considered valid HTML. If you have any say in this I'd recommend requesting the change.
Another option would be to use a regular expression on the raw html.
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")
So I have this element in html :
<input data-v-72dea36a="" type="text" name="tradelink" placeholder="Enter your code" style="margin-right: 25px;">
How can I select exactly this one? I tried:
find_element_by_name('tradelink')
There is another element before this one with the same name...it doesn't have an id or class name...
If there are just 2 elements with attribute name="tradelink", and assuming you need the seconds one, you can use:
find_elements_by_name('tradelink')[1]
Another way is using xpath to match the placeholder value:
find_element_by_xpath("//input[#placeholder='Enter your code']")
Notes:
Notice the plural on elementS on the 1st example
Selenium Docs - Locating Elements
Fore more than 2 elements, you may have to change the array item number, i.e.: find_elements_by_name('tradelink')[2]
Rightclick the element within the inspect element editor and select copy full xpath. As posted above, paste that code into the parentheses in find_element_by_xpath()
I got a input element that I need to clear the actual value and input another one.
The HTML has the following structure:
<input class="input-mini" type="text" name="daterangepicker_start" value="">
I used the following code to find this element:
test = browser.find_elements_by_css_selector("input[type='text'][name='daterangepicker_start']")
Then I got a list of 7 elements and I guess the first one is the one. So a tried to clear the field and after send the new value as following:
test[0].clear()
test[0].send_keys('02/07/2019')
However, for both codes I got the same error:
ElementNotInteractableException: element not interactable
(Session info: chrome=76.0.3809.87)
Sometimes, the element can be under a <div that is considered hidden, I have experienced this before, sometimes you can try .click() to make the element Interactable, like this:
test[0].click()
test[0].clear()
test[0].send_keys('02/07/2019')
In case the above does not allow the element to change to an interactable state, try changing the value with javascript:
browser.execute_script("arguments[0].value = arguments[1]", test[0], "02/07/2019")
I would also recommend to look through the element list and figure out which one within the list is actually the element you're trying to interact with, in case it's not truly test[0].
Use WebDriverWait
test = WebDriverWait(driver, 5).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR , "input[type='text'][name='daterangepicker_start']")))
test[0].clear()
test[0].send_keys('02/07/2019')
I have a web page which i am automating, I can click on any other elements using xpath or name or ID, but this gets little tricky when the element which I want to click is inside label. Here is the example,
<div class="dv-widget dv-deco-def dv-sz-med dv-map-sw">
<input name="l_maps" id="grp_perc" value="0" class="map_HD dv-radio-swr" type="radio">
<label for="grp_percentage" class="dv-radio-swl" onclick="">%</label>
<input name="l_maps" id="grp_count" value="1" class="map_HD dv-radio-swr" checked="" type="radio">
<label for="grp_multiply" class="dv-radio-swl" onclick="">*</label></div>
I need to click on the radio buton with the text % on it, I tried several option using xpath and CSS and ID but nothing seems to find that element under that label. I need help on this guys please. Thank you in advance.
This is kind of a strange situation. Typically the for attribute of the LABEL matches the ID of the INPUT that it corresponds to, e.g.
<input id="name" ... >
<label for="name" ... >
But in this case it doesn't match. We can get around it pretty easily. You can search for the element that contains the % text using XPath and then find the preceding INPUT.
//label[.='%']/preceding-sibling::input
If you plan to use this elsewhere also, I would suggest that you put this into a function and pass in the LABEL text, e.g. % and feed that into the locator to click the matching INPUT.
To click on the radio button with the text as % you can use either of the following lines of code :
Using preceding :
driver.find_element_by_xpath("//label[#class='dv-radio-swl' and #for='grp_percentage']//preceding::input[1]").click()
Using preceding-sibling :
driver.find_element_by_xpath("//label[#class='dv-radio-swl' and #for='grp_percentage']//preceding-sibling::input[1]").click()
Using ancestor :
driver.find_element_by_xpath("//label[#class='dv-radio-swl' and #for='grp_percentage']//ancestor::input[1]").click()
Update
As per the first part of the xpath I have provided it correctly identifies the <label> element with text as %. See the snapshot :
Now, appending preceding makes no mistake to identify the previous <input> tag. See snapshot :
So in all means our xpath is correct. Possibly, you need to induce a waiter for the element to be clickable as follows :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[#class='dv-radio-swl' and #for='grp_percentage']//preceding::input[1]"))).click()
If you are still unable to locate the element check the HTML if the element is within an <iFrame> tag and you will find a detailed discussion in How can I select a html element no matter what frame it is in in selenium?