1

Here I have tried to access leetcode question title, which are available on the given link. However I seem to not be able to access the text in the specified web element. The error I get says:

AttributeError: 'list' object has no attribute 'text'

I also get a warning:

service = Service(executable_path=gecko, log_path='geckodriver.log')
DeprecationWarning: log_path has been deprecated, please use log_output

Please help me fix these, since I cannot find any solution which does not return the same error.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service

# URL of the page with questions
url = 'https://leetcode.com/problemset/all/?page=1&topicSlugs=array'
gecko= 'path'
i = 3
# XPath expression for the elements containing the text
xpath_expression = f"/html/body/div[1]/div/div[2]/div[1]/div[1]/div[5]/div[2]/div/div/div[2]/div[1]/div[2]/div/div/div/div/a"
firefox_path="path"

options = Options()
service = Service(executable_path=gecko, log_path='geckodriver.log')
driver = webdriver.Firefox()
driver.get(url)
element = driver.find_elements(By.XPATH, xpath_expression)
element_text = element.get_attribute('text')
print(element_text)
driver.quit()
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352

3 Answers3

1

The web element returned is a list, so this should work in your case

element_text = element[0].text

but ideally, a list implies several elements so would make sense to iterate over

elements = driver.find_elements(By.XPATH, xpath_expression)

for element in elements:
    element_text = element.text
    print("Element text:", element_text)
vizallati
  • 11
  • 3
1

You are using find_elements method that returns a collection instead of find_element that returns single element. Collection doesn't have attribute text.

To return text from single element, you should use

driver.find_element(By.XPATH, xpath_expression).text

If you want to print all text from elements within collection, you can use loop:

for element in paragraph_elements:
    print(element.text)

Also I suggest to use more concrete xPath expression to locate your element / elements.

Something like CSS selector [role=row] .truncate a

Yaroslavm
  • 1,762
  • 2
  • 7
  • 15
  • Hello, I think I do need a more concrete xPath expression to locate the element(s) But I am not sure how to do so, could you help out there The problem arising here is that when I try to use elements, it is returning an empty list, which I presume means that it doesn't really get to the element I want it to get to I did infact get this selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: /html/body/div[1]/div/div[2]/div[1]/div[1]/div[5]/div[2]/div/div/div[2]/div[1]/div[2]/div/div/div/div/a – amspsingh04 Aug 12 '23 at 11:45
  • Can you make a screen / show, what element or elements are you trying to get? – Yaroslavm Aug 12 '23 at 13:07
  • https://imgur.com/a/snTXDnS I wish to extract "1. Two Sum" as you can see on the left side I have copied its XPath and URL and putting it into this code It still is not running, I do not know how – amspsingh04 Aug 12 '23 at 14:05
  • @amspsingh04 this element can be found by `driver.find_element(By.CSS_SELECTOR, '.truncate [href*=two-sum]')` – Yaroslavm Aug 12 '23 at 14:36
  • 1
    thank you so much, got it done with this and undetected-selenium 's answer – amspsingh04 Aug 13 '23 at 13:15
1

You were almost there. You are looking for the (single) element with text as 63. Unique Paths II. So you instead of find_elements() you need to use find_element().


Solution

However to extract the visible text 63. Unique Paths II ideally you need to induce WebDriverWait for the visibility_of_element_located() and using the index [0] you can use either of the following locator strategies:

  • Using CSS_SELECTOR and text attribute:

    driver.get(url='https://leetcode.com/problemset/all/?page=1&topicSlugs=array')
    elements = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "a[href='/problems/unique-paths-ii/'][class^='h-5']")))
    print(elements[0].text)
    
  • Using XPATH and get_attribute("innerHTML"):

    driver.get(url='https://leetcode.com/problemset/all/?page=1&topicSlugs=array')
    elements = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//a[starts-with(@class, 'h-5') and @href='/problems/unique-paths-ii/']")))
    print(elements[0].get_attribute('innerHTML'))
    
  • Note : You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

You can find a relevant discussion in How to retrieve the text of a WebElement using Selenium - Python


References

Link to useful documentation:

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