Hi3t
Hi3t

Reputation: 51

TypeError: 'WebElement' object is not subscriptable

I try to press the Replay button at Spotify Web Player with Python, but get this error. How can I press buttons in a webplayer?

replay = driver.find_element_by_xpath("""/html/body/div[2]/div/div[4]/div[3]/footer/div/div[2]/div/div[1]/div[5]/button""")[0]
replay.click()

Error:

replay = driver.find_element_by_xpath("""/html/body/div[2]/div/div[4]/div[3]/footer/div/div[2]/div/div[1]/div[5]/button""")[0]
TypeError: 'WebElement' object is not subscriptable

Upvotes: 5

Views: 43715

Answers (5)

alex95
alex95

Reputation: 1

I also encountered this problem, at first I didn't understand what was going on, but it turned out to be quite simple. As it was written above find.element & find.elements work differently. I also realized that when using find.element, 0 element is taken

Upvotes: 0

Andrii
Andrii

Reputation: 144

For everybody, who get this error: you might have confused driver.find_element() with driver.find_elements() and you are trying to get the singular item from WebElement object, not from a list Check it in your code

driver.find_elements() returns a list of appropriate WebElements

There is also another function - driver.find_element() and you can say that:
driver.find_element() = driver.find_elements()[0]


In this example Python is trying to get the first item from driver.find_element() object, which returns a WebElement object, not a list

replay = driver.find_element_by_xpath("""/html/body/div[2]/div/div[4]/div[3]/footer/div/div[2]/div/div[1]/div[5]/button""")[0]

Upvotes: 4

undetected Selenium
undetected Selenium

Reputation: 193138

This error message...

TypeError 'WebElement' object is not subscriptable

...implies that you have attached an index to a WebElement which is not supported.


Analysis

Only list elements can be indexed. However, in this line of code:

replay = driver.find_element_by_xpath("""/html/body/div[2]/div/div[4]/div[3]/footer/div/div[2]/div/div[1]/div[5]/button""")[0]
        

driver.find_element_by_xpath("""/html/body/div[2]/div/div[4]/div[3]/footer/div/div[2]/div/div[1]/div[5]/button""") would always return a single WebElement. Hence you can't access the element through any index, e.g. [0], [1], etc as an index can be associated only with a list.


Solution

There are two approaches to solve the issue.

  • In the first approach, you can remove the index, i.e. [0], and in that case replay will be assigned with the first matched element identified through locator strategy as follows:

    replay = driver.find_element_by_xpath("""/html/body/div[2]/div/div[4]/div[3]/footer/div/div[2]/div/div[1]/div[5]/button""")
    
  • In the other approach, instead of using find_element_by_xpath() you can create a list using find_elements_by_xpath() and access the very first element from the List using the index [0] as follows:

    replay = driver.find_elements_by_xpath("""/html/body/div[2]/div/div[4]/div[3]/footer/div/div[2]/div/div[1]/div[5]/button""")[0]
    

Reference

You can find a couple of relevant discussions in:

Upvotes: 8

dropnz
dropnz

Reputation: 112

find_element_by_xpath

returns first found element (not array)

find_element_by_xpath(...).click()

or

find_elements_by_xpath(...)[0].click()

Upvotes: 3

Moshe Slavin
Moshe Slavin

Reputation: 5204

As @KunduK commented remove the [0].

You are using absolute xPath this is not recommended.

Try using relative xPath...

If there are a few buttons and you need the first use the [0] in the xpath like so:

replay = driver.find_element_by_xpath("""/html/body/div[2]/div/div[4]/div[3]/footer/div/div[2]/div/div[1]/div[5]/button[0]""")
replay.click() 

Upvotes: 0

Related Questions