How to find all elements of form Using Selenium - python

I am trying to get all the elements of form using selenium, but I can't seem to get it done. I need to do it dynamically without writing down the id or class of elements present in the form, The Selenium should detect the form and get all the elements name automatically that are present in the form.
The problem I'm facing is that the form is using action instead of class.
Here is the website
driver = webdriver.Chrome()
driver.get("http://stevens.ekkel.ai")
#find all form input fields via form name
content = driver.find_element_by_class_name('form')
print(content)

You want to print the Name, People, date, Message values of the form?
content = driver.find_element_by_tag_name('form')
for input in content.find_elements_by_xpath('./p/input'):
print(input.get_attribute('name'))
The following would look for any html element with an attribute of name inside the form and print it.
content.find_elements_by_xpath('.//*[#name]')

You can use find_element_by_tag_name:
content = driver.find_element_by_tag_name('form')
This might have problems when there are multiple forms to choose from. Then you have to use find_elements_by_tag_name and potentially choose manually later.

Related

Python Selenium lists only one li repeatedly

I'm trying to make an attendance app, using Selenium; the script should read the names and click on a designated checkbox when a name is matched. What happens is that it keeps clicking on the first checkbox repeatedly. When I looked into it turns out that it only reads the first li only.
here's the HTML code
<div class="members">
<ul class="memberlist"></ul>
</div>
the li are generated via fetch API from the database
when I try these in python, it only reads the first li element over and over
for i in range(len(df)):
print(driver.find_element(By.XPATH,".//ul[#class='memberlist']/li/p").text)
for i in range(len(df)):
print(driver.find_element(By.CLASS_NAME,"name").text)
also, I tried the solution from this and I don't think this is the correct syntax
selenium python for loop printing only first element repeatedly
Update: as per dosas comment, this did list all the names instead of just one, then I wrote this to click on the checkboxes of the attendees.
for i in range(len(df)):
# match names of the sheet with the 'name' class in the webpage
if df['name'][i]==driver.find_elements(By.CLASS_NAME,"name")[i].text:
driver.find_elements(By.CLASS_NAME, week)[i].click()
print(driver.find_elements(By.CLASS_NAME,"name")[i].text)
else:
print('No match')
Now I have a different problem, the attendance excel sheet has to be in the same order as the list on the web page, otherwise, it'll show 'No match'. So how do I make it search the whole page for each particular name?

Python Selenium pulling child property from parent?

I'm trying to scrape a webform for text in specific fields however i can't do it with xpath because some forms are missing fields which won't be included in the page when it loads (i.e. if /html/blah/blah/p[3] is the initials field for one form it might be first name on another form but have the same xpath. The structure for the fields is like this:
<p><strong>Initials:</strong> WT</p>
so using python selenium i'm doing
driver.find_element_by_xpath("//*[contains(text(), 'Initials:')]") which does successfully pull the "Initials:" text between the strong tags but i specifically need the child text after it, in this case WT. It has the attribute "nextSibling.data" which contains the WT value but from my googling i don't think its possible to pull that attribute with python selenium. Does anyone know a way to pull the WT text following the xpath query?
The 'WT' text is in a weird spot. I don't think it is actually a sibling per-se. The only way I know to grab that text would be to use p_element.get_attribute('outerHTML'), which in this instance should grab the string '<p><strong>Initials:</strong> WT</p>'. I doubt this is the cleanest solution, but here's a way to parse that text out:
strong_close_tag = '</strong>'
p_close_tag = '</p>'
p_element = driver.find_element_by_xpath("//*[contains(text(), 'Initials:')]/parent")
print(p_element.get_attribute('outerHTML')[text.index(strong_close_tag)+len(strong_close_tag):text.index(p_close_tag)])
OR -- use p_element.get_attribute('innerHTML'), which should return just <strong>Initials:</strong> WT. Then, similarly, grab the text after the </strong> closing tab, maybe like this:
p_element = driver.find_element_by_xpath("//*[contains(text(), 'Initials:')]/parent")
print p_element.get_attribute('innerHTML').split("</strong>",1)[1]

Need Selenium to return the class title content of given HTML

Using Selenium to perform some webscraping. Have it log in to a site, where an HTML table of data is returned with five values at a time. I'm going to have Selenium scrape a particular bit of data off the table, write to a file, click next, and repeat with the next five.
New automation script. I've a myriad of variations of get_attribute, find_elements_by_class_name, etc. Example:
pnum = prtnames.get_attribute("title")
for x in prtnames:
print('pnum')
Here's the HTML from one of the returned values:
<div class="text-container prtname"><span class="PrtName" title="P011">P011</span></div>
I need to get that "P011" value. Obviously Selenium doesn't have "find_elements_by_title", and there is no HTML id for the value. The Xpath for that line of HTML is:
//*[#id="printerConnectTable"]/tbody/tr[5]/td/table/tbody/tr[1]/td[2]/div/span
But I don't see a reference to "title" or "P011" in that Xpath.
pnum = prtnames.get_attribute("title")
AttributeError: 'list' object has no attribute 'get_attribute'
It's like get_attribute doesn't exist, but there is some (albeit not much) documentation on it.
Fundamentally I'd like to grab that "P011" value and print to console, then I know Selenium is working with the right data.
P.S. I'm self-taught with all of this, I'm automating a sysadmin task.
I think the problem is that prtnames is a list of element, not a specific element. You can use a list comprehension if you want a list of the attributes of titles for the list of prtnames.
pnums = [x.get_attribute('title') for x in prtnames]

return Find_element_by_name as a string In Python

I need some help form all of you, so I have something like this:
element = driver.find_element_by_name("SiteMinderVarForm")
print (element)
When I execute the program I receive:
selenium.webdriver.remote.webelement.WebElement (session="d49d6df9305f2e92eb81aed5c0ed848b", element="0.6436298007036831-4")
And I need a string as result.
I'm trying to automatically login into a web site. If the process of login fails because of an incorrect password or username I need to show a pop up with an error message. So I'm trying to get the name of the form and check if is equal to the actual name. In case it is equal that means the process is successful, and if not the process fails.
If you have any better ideas to do that please let me know.
From your question, it seems like you want the text value contained in the webelement. You can use the webelement.getAttribute("value") method. If you want to get the name attribute of the webelement with name SiteMinderVarForm:
element = driver.find_element_by_name("SiteMinderVarForm")
value = element.getAttribute("name")
print(value)
Similar to Using Selenium Web Driver to retrieve value of a HTML input
More examples at: Get Attribute values using Webdriver
You may also be able to use the webelement.getText() method.
element = driver.find_element_by_name("SiteMinderVarForm")
value = element.getText()
print(value)
Difference between getText() and getAttribute()

Python Selenium HTML class with multiple types and multiple data-binds

This is my first day working with Selenium, so I have not picked up all the tricks. I want to use python to populate many different values into text boxes/drop downs from a website. I need to do this many times, and the values will be different each time.
When using Selenium, the majority of what I need to access is in the form:
<input class="there are several classes" type="text" data-bind="value: value">
Multiple text boxes have the same class, same type but different data-bind values. Every time I try to update values in these text boxes, I am only able to update the first box (and I need access to all text boxes).
The code I've written is:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('website')
a = driver.findElement(By.cssSelector("input.there.are.several.classes.input-sm")).getAttribute("value")
a.clear()
a.send_keys('0.20')
For this code I get AttributeError: 'WebDriver' object has no attribute 'findElement'
I have also tried:
b = driver.find_element_by_css_selector('input.there.are.several.classes.input-sm')
b.clear()
b.send_keys('2')
This works, however it only updates the first text box. I need a way to access text boxes based on their specific value within the same class.
Use find_elements_by_css_selector() and iterate over the found input elements:
for elm in driver.find_elements_by_css_selector('input.there.are.several.classes.input-sm'):
elm.clear()
elm.send_keys("2")
This should work
b = driver.find_elements_by_css_selector('input.there.are.several.classes.input-sm')

Categories

Resources