0

I'm trying to capture an element of a web page using selenium in python

<span class="_2-1_O"><span dir="auto" class="_1jlxc _3Whw5">Ana Smith</span></span>

I'm trying to capture the name Ana Smith in Phyton:

nome_contato =  driver.find_elements_by_class_name("_1jlxc _3Whw5").text

However, python cannot locate

    try:
        name=  driver.find_elements_by_class_name("_1jlxc _3Whw5").text

    except Exception as e:
        print("|False")

Result: |False

imbr
  • 6,226
  • 4
  • 53
  • 65

4 Answers4

1

.text does not need () it's just ".text"

In general it's easier to help with more information, but from the information you gave that's the main issue that I see.

eagleman21
  • 116
  • 3
  • Edited or excerpt, but do not find. I want to access only the name Ana Smith, but the element cannot be found in the code –  Jun 18 '20 at 18:32
  • So that could either be because the page isn't loading quickly enough, so you'd have to use the wait function in selenium but also, find_elements method returns a list, and .text does not work on a list. To get around this you have to either iterate through the list using a for loop and use .text on each iteration or if you really only are looking at one tag you can just make it find_element rather than elements. – eagleman21 Jun 18 '20 at 19:31
0

find_elements_by_class_name returns a list, be careful. You can use find_element_by_class_name if you want the first element or you can select one element of the list returned by find_elements_by_class_name.

Wassel
  • 98
  • 9
0

To handle dynamic element you need to induce WebDriverWait and wait for element to be visisble visibility_of_element_located() and following css selector

Code:

print(WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.CSS_SELECTOR,"._1jlxc._3Whw5"))).text)

you need to import following libraries

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
KunduK
  • 32,888
  • 5
  • 17
  • 41
0

You have to consider a couple of things:

  • find_elements_by_* will return a list. But you want that particular element. So you have to use find_element_by_* instead.
  • driver.find_element_by_class_name() takes a single class. So it won't accept multiple classes as in:

    driver.find_element_by_class_name("_1jlxc _3Whw5")
    
  • Most important, the element is a dynamic element, so to print the text Ana Smith you have to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategies:

    • Using CSS_SELECTOR and get_attribute("innerHTML"):

      print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "element_css"))).get_attribute("innerHTML"))
      
    • Using XPATH and text attribute:

      print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "element_xpath"))).text)
      
  • However, the value(s) ofthe class attribute, _1jlxc, _3Whw5, etc indicates that the values are generated by either ReactJS, Vue.js, etc. So those values are never static and they would keep on changing everytime you access the webpage.


Solution

Apart from inducing WebDriverWait you have to construct either or based on static attributes possibly from some ancestor elements.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352