Cannot locate element using Selenium - python

I am using Selenium with Python and Chromedriver to click on a "button" (not actually a button in the HTML, but looks like one on screen and is clickable). The HTML is below, I am trying to click on the one with the 'button-new' id.
<td class="read" colspan="4">
Read
<a id="button-new" title="Read new record from database" class="button button-new">New</a>
</td>
I have tried using:
new_button = driver.find_element_by_id("button-new")
new_button = driver.find_element_by_css_selector("A.button.button-new")
new_button = driver.find_element_by_xpath('//*[#id="button-new"]')
followed by
new_button.click()
But I get the NoSuchElementException and it cannot locate it.
I've not had this problem with any other elements and not sure where I'm going wrong.
EDIT with solution:
I realised I needed to switch iframe
driver.switch_to.frame(driver.find_element_by_id("nested1"))

To make sure whether the element is being located try this:
new_button_list = driver.find_elements_by_xpath('//a[#id="button-new"]')
this will return a list because of using 'elements':
then check the length of the list, one good thing is it wont through an exception and also let you know whether the element is located.

try to use it with if statement, maybe they put special a empty button to confuse us,
new_button = driver.find_element_by_id("button-new")
if new_button:
new_button.click()
can you check with find_elements_by_id how many btn are there ?
btns = driver.find_elements_by_id("button-new")
print(btns)
# also we can check with # find_elements_by_id
btns = driver.find_elements_by_id("button-new")
if len(btns):
new_button[0].click()

Related

XPATH syntax for element in {} with Selenium for Python

I am currently trying to click each button on a webpage with Selenium in Python, the class and text is always the same for each button but each button has different ids. The ids, however, are within "data-paramaters" in {} and I can't figure out how to get the correct syntax for the xpath.
Here is a snippet of the website for one of the buttons:
<span class="contains-icon-details gc-btn gc-btn--s" data-isneededpromise="false" data-parameters="{"partner":"gs", "realId": "8da1d6a9-44d1-4556-bc12-92699749a30a", "tnId": "102086182829", "type": "details"}">More Details</span>
It seems the realId and the tnId are unique, so I would need to find the buttons with either one of those.
This works:
driver.find_element_by_xpath("//span[#class='contains-icon-details gc-btn gc-btn--s']").click()
but of course only for the first button as the class is always the same.
I tried something like this:
driver.find_element_by_xpath("//*[contains(#tnId, '102086182829')]").click()
but I get
Unable to locate element: //*[contains(#tnId, '102086182829')]
so definitely not the correct syntax.
I tried to find a solution online, but with no luck so far. Can anybody point me into the right direction? Thanks in advance.
In case realId value or tnId value is unique your XPath can be
driver.find_element_by_xpath("//*[contains(#data-parameters, '8da1d6a9-44d1-4556-bc12-92699749a30a')]").click()
or
driver.find_element_by_xpath("//*[contains(#data-parameters, '102086182829)]").click()
you should filter by the "data-parameters" attribute.
Try
driver.find_element_by_xpath("//span[contains(#data-parameters, '102086182829')]").click()
This is a dirty implementation of what you need. It would be better to extract the data-parameters field, deserialize JSON and check for the needed field;
spans = driver.find_element_by_xpath("//span[#class='contains-icon-details gc-btn gc-btn--s']")
for span in spans:
data_parameters = span.get_attribute("data-parameters")
try:
data_parameters = json.loads(data_parameters)
except:
continue
if 'tnId' in data_parameters and data_parameters['tnId'] == "102086182829":
span.click()
break

i have a question to select xpath in sellenium(python)

i was trying to click some button in the page but it changes when it is available so that mine is not working.
basically, normally it's the only one section but changes into one that contains multiple buttons. and i am aiming to click buying or another buttons when it shows but i kept failing.
when it's unavailable(to click buying or shipping button), it looks like this.
<div class="XqRGHcrncz">
<ul class="_3YA58cPPsy">
<li class="_3nAZvQO51p N=a:pcs.mylist">
<a href="javascript:void(0)" role="button" class="_3Dy-2NaoiG" aria-pressed="false">
<span class="_3nBu7xChUl"><span class="blind">찜하기</span></span>
<em class="_1c-2nfzJqH">13</em></a></li></ul></div>
but when it is available, buying button appears. everything is same but the starting from
li class, it changes a bit.
li class became
<li class="_3nAZvQO51p N=a:pcs.mylist">
and the rest changed too.
<a href="javascript:void(0)" class="OgETmrvExa">
<span class="blind">구매하기</span>
how can i make xpath to click the element that shows only available?
the main problem is that div is changing.
xpath is sometimes
//*[#id="content"]/div/div[2]/div[2]/fieldset/div[7]/ul[1]/li/a
but sometimes it is
//*[#id="content"]/div/div[2]/div[2]/fieldset/div[8]/ul[1]/li/a
so that the div[] is changing. i tried css selector to click it when it turned into new page,
buy=driver.find_css_selector(div.XqRGHcrncz)
lists = buy.find_elements_by_tag_name("ul")
if len(lists) == 2: buy.click()
but when the page is loaded to available, it is not working at all...
i was trying to use xpath like this,
while True:
lists = buy.find_elements_by_tag_name("ul")
if len(lists) == 2:
break
else:
print("구매불가")
driver.refresh()
driver.implicitly_wait(10)
and then
driver.implicitly_wait(10)
xpath='//*[#id="content"]/div/div[2]/div[2]/fieldset/div[8]/ul[1]/li/a'
driver.find_element_by_xpath(xpath).click()
but as i mentioned, the xpath is changing and there is no use. the div[number] <- this changes so that it does not working as it is wrong xpath.
what should i do?? i would be really appreciate if anyone helps me.
(just in case, this is my page that i want to click when it became available...
https://smartstore.naver.com/hwaflora/products/5192517936 thank you)
Try to find element by text, is it stable?구매하기
so the code looks like that:
driver.find_element(By.XPATH, "//span[text()='구매하기']"
or by preceding xpath feature:
driver.find_element(By.XPATH, "//a/preceding::span[text()='찜하기']")
The xpath of your element is
String button = "//li[contains(#class,'_3nAZvQO51p N')]/a"
Now, you mentioned that until it is available there are more elements below it, for example this:
String loading = "//li[contains(#class,'_3nAZvQO51p N')]/a//em"
You can wait until this element disappears. The syntax in Java is:
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until((ExpectedConditions.invisibilityOfElementLocated(By.xpath(loading))));
Now you can find and click the button element

How to let selenium edit an element

I currently am writing a script for web automation but I want the program to edit an element for me here's a sample of the code I'm using
final = driver.find_element(By.XPATH,"//button[contains(text(),'Change profile name')]")
final.click()
now it won't click it since the website has the element set it false so I want selenium to edit and make the element true so it can click it, is that possible by any chance and if so can anyone explain and thanks!
Heres what the elements HTML look like
button class="btn btn-disabled" type="submit" data-testid="ChangeNameButton" aria-describedby="changeNameFormError" aria-disabled="true" data-bi-type="button">Change profile name
so instead of btn disabled, I want it to change it to enabled then click it and thanks in advance for any help submitted :)
The button you are trying to click is disabled and you can enable it with JS.
Something like this:
final = driver.find_element(By.XPATH,"//button[contains(text(),'Change profile name')]")
driver.execute_script("arguments[0].setAttribute('className', 'btn-enabled');", final)
To change the text of an element do something like the following:
driver.execute_script("document.getElementById('theelement').innerHTML = 'changed text';");
To change or set attribute of element:
element = driver.find_element_by_class_name("NAMEOFELEMENT");
driver.execute_script("arguments[0].setAttribute('color: blue;')", element);

Selenium not clicking element

I have the following checkbox element:
<input checked="checked" class="iceSelBoolChkbx"
id="mainContentId:newSerchCheckBox" name="mainContentId:newSerchCheckBox"
onblur="setFocus('');"
onclick="var form=formOf(this);iceSubmitPartial(form, this, event);"
onfocus="setFocus(this.id);"
onkeypress="var form = formOf(this);
Ice.util.radioCheckboxEnter(form,this,event);"
type="checkbox">
I currently am locating the element and attempting to click it using
check_box = driver.find_element_by_id('mainContentId:newSerchCheckBox')
check_box.click()
When I run the code it runs without any errors but on the site the checkbox is still unchecked. What could be causing this and is their an alternative way to check the box?
Try replacing click with mousedown, I don't know what the underlying difference is but it resolved the issue I was having with click().
driver.execute_script('$("#mainContentId:newSerchCheckBox").trigger("mousedown")')
Let me know if you're thrown an error and we can re-write it in pure Javascript rather than relying on jQuery.
I think your checkbox is already selected if you see the input tag checked="checked".So you need to check first whether selected or not.If selected do not click.
element=driver.find_element_by_id("mainContentId:newSerchCheckBox")
if element.is_selected():
print('Check box is already selected')
else:
element.click()

Using Selenium in Python to click/select a radio button

I am trying to select from a list of 3 buttons, but can't find a way to select them. Below is the HTML I am working with.
<input name="pollQuestion" type="radio" value="SRF">
<font face="arial,sans-serif" size="-1">ChoiceOne</font><br />
<input name="pollQuestion" type="radio" value="COM">
<font face="arial,sans-serif" size="-1">ChoiceTwo</font><br />
<input name="pollQuestion" type="radio" value="MOT">
<font face="arial,sans-serif" size="-1">ChoiceThree</font>
I can find it by using the following code:
for i in browser.find_elements_by_xpath("//*[#type='radio']"):
print i.get_attribute("value")
This outputs: SRF,COM,MOT
But I would like to select ChoiceOne. (To click it) How do I do this?
Use CSS Selector or XPath to select by value attribute directly, then click it.
browser.find_element_by_css_selector("input[type='radio'][value='SRF']").click()
# browser.find_element_by_xpath(".//input[#type='radio' and #value='SRF']").click()
Corrections (but OP should learn how to look up in documentation)
In Python binding, find_elements_by_css doesn't exist, it's called find_elements_by_css_selector. One should be able to look at the exception message and look back into documentation here and figure out why.
Notice the difference between find_element_by_css_selector and find_elements_by_css_selector? The first one finds the first matching element, the second one finds a list, so you need to use [0] to index. Here is the API documentation. The reason why I use the latter, is because I copied your code, which I shouldn't.
Selenium webdriver Radio button click
When i used xpath :
driver.find_element_by_xpath("//input[#id='id_gender2']").click()
radio button not selected
But I used css_selector :
driver.find_element_by_css_selector("input#id_gender1").click()
radio button selected
find_elements_by_css_selector worked for me,
browser.find_elements_by_css_selector("input[type='radio'][value='SRF']")[0].click()
First Radio button was not selected for me also. But after inserting Time it works for me.
driver.find_element_by_class_name("login").click()
driver.find_element_by_id("email_create").send_keys("testsel000#gmail.com")
driver.find_element_by_id("SubmitCreate").click()
time.sleep(2)
driver.find_element_by_css_selector("#id_gender2").click()
Consider that you have a radio button to select either of the two options, "Male or "Female". Then try using the following :- This is in Python (Selenium).
driver.find_element_by_xpath("//label[contains(text(),'Male')]").click()
browser.find_elements_by_xpath(".//input[#type='radio' and #value='SRF']")[0].click
This ended up being the fix. I was getting errors without the [0] there, that a list does not have a click() attribute (even though there was only 1 match). Thanks for the help user1177636!

Categories