Selenium Python 2 find element by name and value? - python

I have been trying to locate an element on a web page, this element has the same name as other elements and no id. It does have a different value, so I would like to find the element by the name AND the Value.
in my web page I have a search button:
<input name="action" value=" Search " style=" border-style2; font-size: 11;
font-family: arial, helvetica" border="0" type="submit">
I can't use name because I have another element with the same name and type:
<input name="action" value=" Go " onclick=" return custRange('cust', 'd_custno');"
style=" border-style2; font-size: 11; font-family: arial, helvetica"
border="0" type="submit">
I therefore tried to use xpath, I started by using the xpath checker to return the xpath which returned:
/x:html/x:body/x:center/x:table/x:tbody/x:tr/x:td/x:center/x:center[1]/x:table[2]/x:tbody/x:tr/x:td[1]/x:table[3]/x:tbody/x:tr[5]/x:td[2]/x:input[2]
Again pretty new to this but I'm assuming the "x:" shouldn't be in the path so I removed this and tried to find the element with the following:
search = driver.find_element_by_xpath("//center[1]/table[2]/tbody/tr/td[1]/table[3]/tbody/tr[5]/td[2]/input[2]")
search.clickAndWait()
which resulted in:
selenium.common.exceptions.NoSuchElementException: Message: 'Unable to find element with xpath == //center[1]/table[2]/tbody/tr/td[1]/table[3]/tbody/tr[5]/td[2]/input[2]'
So really I have 2 questions it would be great if someone could help with:
is there a way to identify an element by name and value?
obviously I'm missing something with xpath, is the way I'm trying to use xpath incorrect? if so could you suggest what I'm doing wrong?
Any help greatly appreciated.
for completeness my unittest code is is as follows:
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
class umLoginTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Ie()
self.driver.implicitly_wait(3)
def test_login_to_um(self):
driver = self.driver
result_file = open("umLoginTest_result.txt", "w")
driver.get("http://ps-iweb/UserManage/Home")
self.assertIn("Welcome", driver.title)
elem = driver.find_element_by_name("userLogin")
elem.send_keys("pstevenson")
password = driver.find_element_by_name("sec_password")
password.send_keys("etc")
password.send_keys(Keys.RETURN)
test1 = driver.title
result_file.write(str(test1))
select = driver.find_element_by_name("conn_marketid")
for option in select.find_elements_by_tag_name('option'):
if option.text == 'Int Rate Swaps':
option.click()
search = driver.find_element_by_xpath("//center[1]/table[2]/tbody/tr/td[1]/table[3]/tbody/tr[5]/td[2]/input[2]")
search.clickAndWait()
result_file.close()
if __name__ == "__main__":
unittest.main()

Try this
//input[#name='action' and #value=' Search ']

Answering your questions,
1 - Yes you can,
driver.find_element_by_name(‘foo’)
http://selenium-python.readthedocs.org/en/latest/api.html#selenium.webdriver.remote.webdriver.WebDriver.find_element_by_name
2 - I always try to avoid xpath because sometimes it doesn't work properly. Instead, you should always try to find by name or id .. I think is the best case.

Following is the Java code, which i tried with your 2 controls specified above.
driver= new FirefoxDriver();
driver.get("file:///D:/Programming%20Samples/Input.html");
driver.findElement(By.xpath("//*[#name='action'][#value='Go']")).click();
driver.findElement(By.xpath("//*[#name='action'][#value='Search']")).click(); //observed here in your HTML i see some spaces. Make sure giving the right value.
Hope above helps.

driver.find_element_by_xpath("//*[#value=' Search ']").click()
will definitely help.

Related

Python selenium ElementNotInteractableException: Message: element not interactable

I am trying to login to beeradvocate.com to scrape (crawl) some beer data.
I tried with selenium but have been brutally failing.
here is the html
<input type="text" name="login" value="" id="ctrl_pageLogin_login" class="textCtrl" tabindex="1" autofocus="autofocus" style="background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII="); cursor: auto;">
i tried using name and value and class but everything has failed.
I attempted Xpath as my final try, but have failed as well.
website and inspection
My code:
driver=webdriver.Chrome("~~~~\\chromedriver.exe")
driver.get("https://www.beeradvocate.com/community/login/")
from selenium.common.exceptions import TimeoutException
driver.maximize_window()
while True:
try:
WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.XPATH,'//*[#id="ctrl_pageLogin_login"]'))).send_keys("scentmaster")
break
except TimeoutException:
print("too much time")
I've made the button work with:
button = driver.find_element_by_xpath('//*[#id="pageLogin"]/dl[3]/dd/input')
driver.execute_script("arguments[0].click();", button)
However, I need to be able to perform sent_keys to type in id and pw to log in...
Anybody got some idea?
There are 2 fields on the page if you use xpath //*[#id = "ctrl_pageLogin_login"], the input field you are referring to is the second. Sadly, the selenium find element by default refers to the first. It will work if you make it like this: (//*[#id = "ctrl_pageLogin_login"])[2].
But I have another suggestion, try to locate element by css selector with this value : form#pageLogin input#ctrl_pageLogin_login
WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.CSS_SELECTOR,'form#pageLogin input#ctrl_pageLogin_login'))).send_keys("scentmaster")
#for password
driver.find_element_by_css_selector('form#pageLogin input#ctrl_pageLogin_password').send_keys('your_password')
#for submit
driver.find_element_by_css_selector('form#pageLogin input[type=submit]').click()
To feed the username, try this xpath:
'//form/dl/dd/input[#id="ctrl_pageLogin_login"]'
for the password:
'//form/dl/dd/input[#id="ctrl_pageLogin_password"]'
WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.CSS_SELECTOR,'form#pageLogin input#ctrl_pageLogin_login'))).send_keys("scentmaster")
#for password
driver.find_element_by_css_selector('form#pageLogin input#ctrl_pageLogin_password').send_keys('your_password')
#for submit
driver.find_element_by_css_selector('form#pageLogin input[type=submit]').click()
The solution above given by frianH worked! :)

Selenium changing html on a page with python

<div id="modalContent" style="opacity: 1; top: 35%;">
</div>
Say I want to delete this on everytime I go to a particular website.
driver = webdriver.Chrome()
driver.get("some url")
#driver.removeelement("""<div id="modalContent" style="opacity: 1; top: 35%;">
#</div>""")
Is there a way to do this?
To do this, you should execute some javascript on the DOM element. Here is how I would do it.
driver.execute_script("document.getElementById('modalContent').remove()")
Should work.

Change Element Attribute Using XPATH / Send_Keys - Selenium Python

I am writing a program to gather data from a website, however at some point in the program I need to enter an email and password into text boxes. The route I am attempting to go is to use driver.execute_script to change the underlying HTML, however I am having difficulty connecting that command with the XPATH value that I use to find the element. I know there are a few threads on here that deal with similar issues, however I have been completely unable to find one that uses XPATH. Any help would be greatly appreciated as I am totally stuck here.
Below is the line of HTML that I am attempting to change, as well as the XPATH value associated with the text box.
XPATH Value
/html/body/center/div[4]/table[2]/tbody/tr/td[4]/table[1]/tbody/tr[2]/td/table/tbody/tr[7]/td[2]/font
HTML:
<input onclick="if (this.value == 'Enter Your Name') this.value='';" onchange="if (this.value == 'Enter Your Name') this.value='';" name="name" type="text" value="Enter Your Name" style="padding-top: 2px; padding-bottom: 6px; padding-left: 4px; padding-right: 4px; width:120px; height:15px; font-size:13px; color: #000000; font-family:Trebuchet MS; background:#FFFFFF; border:1px solid #000000;">
I am attempting to replace value = "Enter Your Name" with value = "Andrew" - or any other name for that matter. Thank you very much for any and all advice, and please let me know there is any additional data / info that is required.
Send_Keys scripts:
name = driver.find_element_by_xpath('//body/center/form/span/table/tbody/tr/td[1]/input')
name.clear()
name.send_keys("Andrew")
Your <input> tag is contained within an <iframe>, so you'll need to switch the context to the <iframe> first:
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
Now that you're "inside" the <iframe>, your send_keys script should work:
name = driver.find_element_by_xpath('//body/center/form/span/table/tbody/tr/td[1]/input')
name.clear()
name.send_keys("Andrew")
Lastly, here's how to switch back to the default content (out of the <iframe>):
driver.switch_to.default_content()

selenium python: how to send keys to a hidden password with differnet IDs

I'm currently using selenium with python 2.7 and I'm trying to to insert a password to the following form:
<tr id="mockpass">
<td>
<input type="text" value="something1" onfocus="document.getElementById('mockpass').style.display='none';
document.getElementById('realpass').style.display=''; document.getElementById('Irealpass').focus();">
</td>
</tr>
<tr id="realpass" style="display: none;">
<td>
<input type="password" name="Password" id="Irealpass" onblur="if(this.value=='') {document.getElementById('mockpass').style.display='';
document.getElementById('realpass').style.display='none';}">
</td>
</tr>
I tried using the following code but I keeping getting an error while trying to excute the clear command:
passBoxXpath='//*[#id="mockpass"]/td/input'
passBoxElement = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath(passBoxXpath))
passBoxElement.click()
passElement = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath('//*[#name="Password"]'))
passElement = driver.execute_script("arguments[0].style.display = 'block'; return arguments[0];",
passElement)
passElement.clear()
passElement.send_keys("myPassword")
The error:
raise exception_class(message, screen, stacktrace)
InvalidElementStateException: Message: Element is not currently interactable and may not be manipulated
I'm not sure if it's something to do with the focus or the blur that changes the element, but I get the element and fail to accsses it.
Thanks in advance!
update: the next line solved my case (still don't know why it didn't work):
driver.execute_script('document.getElementById("Irealpass").setAttribute("value","myPassword");')
In this way I didn't need to use the passBoxElement at all or changing the display style.
According to the docs http://selenium-python.readthedocs.io, this code should work.
elem = driver.find_element_by_css_selector("#mockpass input:first-child")
If you get the error anyway, scroll the browser window to element you are trying to access.
A couple things...
First off, if you are trying to perform user scenarios, you want to avoid using JavascriptExecutor (JSE). JSE allows you to do things on a page that an actual user cannot. Avoid using JSE unless you absolutely have to or if you don't care about user scenarios.
The problem is that the input that you want is hidden in the HTML you provided. You can see that in the 2nd TR, style="display: none;". If you look in the HTML of the first INPUT, you will see that the onfocus hides the first TR
onfocus="document.getElementById('mockpass').style.display='none';
and then unhides the 2nd TR
document.getElementById('realpass').style.display='';
So what you need to do is to focus the first INPUT which will expose the second INPUT.
One thing to note, from the JS in the second INPUT it looks like if you value is empty, it will rehide the second INPUT and expose the first (undoing what you just did).
onblur="if(this.value=='') {docum ...
I would do something like this
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable(By.XPATH, '//*[#id="mockpass"]/td/input')).click()
wait.until(EC.element_to_be_clickable(By.XPATH, '//*[#id="Irealpass"]')).send_keys("myPassword")
Below should be work:
passwdEle = self.driver.find_element(by='id', value='Irealpass')
self.driver.execute_script('arguments[0].setAttribute("value","****")', passwdEle)

Get the title of a td class with the Selenium Webdriver in Python

I am very new to Selenium and Python in general. I want to get the title of a td class, the HTML code looks like this. I only need to get the 6,012,567 number to use later:
<td class="infoStats__stat link-light border-light-right">
<a href=“/follow" class="infoStats__statLink link-light" title="6,012,567">
<h3 class="infoStats__title font-light”>Users</h3>
<div class="infoStats__value font-tabular-light">6.01M</div>
</a>
</td>
So far I have this:
#element = WebDriverWait(driver, 2).until(EC.presence_of_element_located((By.XPATH, '//td[contains(#class, "infoStats__statLink")]')))
#users = int(element.text.replace(',', ''))
But this is just giving me the 6.01 abbreviation, is there a better way to do this?
Use following code to get required value:
value = int(driver.find_element_by_xpath('//a[#class="infoStats__statLink link-light"]').get_attribute("title"))
Let me know if any errors occurs
Use the below XPath:-
//a[#class='infoStats__statLink link-light']/#title
Use code as below :-
elem = driver.find_elements_by_xpath("//a[#class='infoStats__statLink link-light']/#title");
print elem.text
Hope it will help you :)

Categories

Resources