I have around 20 elements to find by xpath. I'm using this.
e1 = element.find_element_by_xpath('.//div[contains(@class, "myclass")]').text
When element is not found, it throws NoSuchElementException.
One solution would be to use: find_elements_by_xpath instead.
e1 = element.find_elements_by_xpath('.//div[contains(@class, "myclass")]')
# Then check for length
if len(e1) > 0:
text1 = e1[0].text
That's 3 lines of codes for one single element.
If I use try, except as well, there will be 60 lines of code
more for such a trivial task.
How to handle this elegantly? Also, is there any way to find text directly from xpath instead of doing element.text like:
# This should return text inside of that element
text = element.find_element_by_xpath('.//div[contains(@class, "myclass")]/text()')
The simplest and best practice way, according to the Selenium docs, to do this is to use .find_elements() as you suggested just wrap it in a function to make it more reusable, keep your code DRY, and make your code easier to read.
Rather than restricting locators to just XPath, instead use a By in your method.
from selenium.webdriver.common.by import By
def get_text(element, locator):
elements = element.find_elements(locator)
if len(elements) > 0:
return elements[0].text
return ""
NOTE: Return "" (empty string) here instead of None. If you return None when it's not found, you will have to check for None when doing something with the return or you'll get an exception.
Then you call it like
e1 = get_text(element, (By.XPATH, './/div[contains(@class, "myclass")]'))
or better yet, use a CSS selector because it's faster, better supported, and in this scenario less likely to give you unintended elements.
e1 = get_text(element, (By.CSS_SELECTOR, "div.myclass"))
Also, you can't use /text() in an XPath in a browser because browsers only support XPath 1.0 and /text() is in a later version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With