Keep bumping into the same problem: when I use Selenium (Python), I often need to find the element to send_keys() to. E.g. on ebay front webpage, need to search for some item.
Each time I end up tring all the classes/frames around what I need (sometimes with ChroPath) and one of them works. Is there a simpler and more systematic way to find the element corresponding to search tab to send keys to?
Well one thing you could try is using hasattr method to check if the element has a particular attribute or not. From the official documentation about hasattr
hasattr(object, name) The arguments are an object and a string. The
result is True if the string is the name of one of the object’s
attributes, False if not. (This is implemented by calling
getattr(object, name) and seeing whether it raises an AttributeError
or not.)
if hasattr(element, 'send_keys'):
# do something
No, you shouldn't try to invoke send_keys() on random elements on a webpage, e.g. ebay homepage.
Ideally, the WebElements with whom you would interact or invoke send_keys() should be part of your tests and should also be a part of the Test Plan.
While you execute your tests, in the due coarse you may encounter different errors when send_keys() is being invoked. You have a to address the issues as they show up as per the prevailing condition of the HTML DOM.
References
You can find a couple of relevant discussions on send_keys() in:
How to insert a value in a field Text using Selenium?
Using Selenium in Python to enter currency format text
Related
I am trying to do something i can't find any help on. I want to be able to locate the xpath or other 'address' information in of a particular element for later use by selenium. I have text for the element and can find it using the selenium By.LINK.TEXT methodology. However, i am writing an application where speed is critical so i want to pre-find the element, store the xpath (for later use) and then use the By.XPATH methodology. In general finding an element using the BY.text construction takes .5 seconds whereas the xpath lookup takes on 10 - 20% of that time. I tried the code below but i get an error on getpath (WebElement object has no attribute getpath)
Thanks for any help
temp = br.find_element(By.LINK_TEXT, (str(day_to_book)))
print(temp.getpath())
The Selenium WebElement object received by driver.find_element(ByLocator) is already a reference to the actual physical web element on the page. In other words, the WebElement object is an address of the actual web element you asking about.
There is no way to get a By locator of an already found WebElement
So, in your particular example temp = br.find_element(By.LINK_TEXT, (str(day_to_book))) the temp is an address of the element you can keep for future use (until the page is changed / refreshed)
I have working code:
options_elements = issn_dropdown.find_elements_by_xpath("//ul[contains(#id,'my_id')]//li")
options = [x.text for x in options_elements]
options_elemets is an array of 5 selenium.webdriver.remote.webelement.WebElement, each of them contains text. The result option is exactly what I need. Why can't I change it to:
options = issn_dropdown.find_elements_by_xpath("//ul[contains(#id,'my_id')]//li/text()")
? Test just fails on this line with no particular error displayed.
text() in the xpath returns text node, Selenium doesn't support it. Your first code block is the way to go.
You saw it right. find_elements_by_xpath("//ul[contains(#id,'my_id')]//li/text()") would just fail using Selenium.
We have discussed this functionality in the following discussions
Treatment of DOM Text Nodes in mixed content nodes
Enhancement request: access to text nodes
Add support for interacting with text nodes
The WebDriver Specification directly refers to:
Contexts in which this element can be used
Element nodes are simply known as elements
and none of them precludes a WebElement reference from being a Text Node.
So the bottom line was, as the specification does not specify local end APIs. Client bindings are free to choose an idiomatic API that makes sense for their language. Only the remote end wire protocol is covered here.
#Simon Stewart concluded:
One option might be to serialize a Text node found via executing javascript to be treated as if it were an Element node (that is, assign it an ID and refer to it using that). Should a user attempt to interact with it in a way that doesn't make sense (sending keyboard input, for example) then an error could be returned.
Hence, your first option is the way to go:
options_elements = issn_dropdown.find_elements_by_xpath("//ul[contains(#id,'my_id')]//li")
options = [x.text for x in options_elements]
For each vendor in an ERP system (total # of vendors = 800+), I am collecting its data and exporting this information as a pdf file. I used Selenium with Python, created a class called Scraper, and defined multiple functions to automate this task. The function, gather_vendors, is responsible for scraping and does this by extracting text values from tag elements.
Every vendor has a section called EFT Manager. EFT Manager has 9 rows I am extracting from:
For #2 and #3, both have string values (crossed out confidential info). But, #3 returns null. I don’t understand why #3 onward returns null when there are text values to be extracted.
The format of code for each element is the same.
I tried switching frames but that did not work. I tried to scrape from edit mode and that didn’t work as well. I was curious if anyone ever encountered a similar situation. It seems as though no matter what I do I can’t scrape certain values… I’d appreciate any advice or insight into how I should proceed.
Thank you.
Why not try to use
find_element_by_class_name("panelList").find_elements_by_tag_name('li')
To collect all of the li elements. And using li.text to retrieve their text values. Its hard to tell what your actual output is besides you saying "returns null"
Try to use visibility_of_element_located instead of presence_of_element_located
Try to get textContent with javascript fo element Given a (python) selenium WebElement can I get the innerText?
element = driver.find_element_by_id('txtTemp_creditor_agent_bic')
text= driver.execute_script("return attributes[0].textContent", element)
The following is what worked for me:
Get rid of the try/except blocks.
Find elements via ID's (not xpath).
That allowed me to extract text from elements I couldn't extract from before.
You should change the way of extracting the elements on web page to ID's, since all the the aspects have different id provided. If you want to use xpaths, then you should try the JavaScript function to find them.
E.g.
//span[text()='Bank Name']
This is the first question I've posted so do let me know if I should make the question clearer. Furthermore I've only just started out Python so I hope I can phrase the question right with the correct terms.
Basically I have created a customizable webscraper that relies on user's knowledge of CSS selectors. Users will first have to go to the website that they want to scrape and jot down the css selectors ("AA") of their desired elements and enter it in an excel file, in which the python script will read the inputs and pass it through browser.find_elements_by_css_selector("AA") and get the relevant text though .text.encode('utf-8')
However I noticed that sometimes there might be important information in the attribute value that should be scraped. I've looked around and found that the suggestion is always to include .get_attribute()
1) Is there an alternative to getting attribute values by just using browser.find_elements_by_css_selector("AA") without using browser.find_elements_by_css_selector("AA").get_attribute("BB"). Otherwise,
2) Is it possible for users to enter some value in "BB" in browser.find_elements_by_css_selector("AA").get_attribute("BB") such that only browser.find_elements_by_css_selector("AA") will run?
Yes, there is an alternative to retrieve the text attribute values without without using get_attribute() method. I am not sure if that can be achieved through css or not but through xpath it is possible. A couple of examples are as follows :
//h3[#class="lvtitle"]/a/text()
/*/book[1]/title/#lang
I'm using webdriver to test a specific page which sometimes will have options disabled in a form.
I'm trying to select the value directly, and then check whether or not it is enabled.
Here's what I have :
hourly = driver.find_element_by_xpath("//select[#name='frequency']/option[#value='HOURLY']")
self.assertFalse(hourly.isEnabled());
The full path is:
/html/body/div[#class='options']/form/select[#name='frequency']/option[#value='HOURLY']
When I run this snippet, I get the following :
AttributeError: 'WebElemet' object has no attribute 'isEnabled'
Which leads me to think that either:
I'm selecting the wrong thing or..
The thing I'm selecting isn't actually a WebElement as I could only find reference to isEnabled in the API under the remote driver (http://selenium.googlecode.com/svn/trunk/docs/api/py/webdriver_remote/selenium.webdriver.remote.webelement.html), which wouldn't be the same thing since I'm just using Selenium Webdriver in Python.
Nevermind, I've been googling so many different docs I forgot entirely just to read the api. The call should be :
is_enabled()
rather than
isEnabled()