Reputation: 97
I am trying to use selenium to extract a list of cases from the top bar (confirmed, active, recovered, deceased) of this Covid website for both daily and cumulative. Trying to do so via a list for the top-level class (= 'Level') and then use XPATH for h1 and h4 tags. But I keep getting an 'unable to locate element' error. What am I doing wrong? I've also tried using a wait time but doesn't seem to help.
from selenium import webdriver
from time import sleep
from selenium.webdriver.support import expected_conditions as EC
PATH = 'ChromeDriver/chromedriver'
driver = webdriver.Chrome(PATH)
driver.get('https://www.covid19india.org/')
sleep(5)
confirmed = driver.find_elements_by_class_name('Level')
for item in confirmed:
daily = item.find_element_by_xpath('.//*[@id="root"]/div/div[2]/div[1]/div[2]/div[1]/div[1]/h4').text
cumulative = item.find_element_by_xpath('.//*[@id="root"]/div/div[2]/div[1]/div[2]/div[1]/div[1]/h1').text
print(daily, cumulative)
print(confirmed)
And here's the traceback:
Traceback (most recent call last):
File "/Users/rssaiki/Programming/Youtube/covid_selenium.py", line 14, in <module>
daily = item.find_element_by_xpath('.//*[@id="root"]/div/div[2]/div[1]/div[2]/div[1]/div[1]/h4').text
File "/Users/rssaiki/Programming/venv/lib/python3.9/site-packages/selenium/webdriver/remote/webelement.py", line 351, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "/Users/rssaiki/Programming/venv/lib/python3.9/site-packages/selenium/webdriver/remote/webelement.py", line 658, in find_element
return self._execute(Command.FIND_CHILD_ELEMENT,
File "/Users/rssaiki/Programming/venv/lib/python3.9/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
return self._parent.execute(command, params)
File "/Users/rssaiki/Programming/venv/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/Users/rssaiki/Programming/venv/lib/python3.9/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":".//*[@id="root"]/div/div[2]/div[1]/div[2]/div[1]/div[1]/h4"}
(Session info: chrome=90.0.4430.93)
Upvotes: 1
Views: 660
Reputation: 5214
As The @Prophet said Level has only one element.
You should not use the absolute path for your Xpath's, use WebDriverWait instead of sleep.
Here is a snip you can find helpful:
WebDriverWait(driver, 30).until(EC.presence_of_all_elements_located((By.XPATH,"//div[contains(@class, 'level-item')]")))
a = driver.find_elements_by_xpath("//div[contains(@class, 'level-item')]//h5")
b = driver.find_elements_by_xpath("//div[contains(@class, 'level-item')]//h4")
c = driver.find_elements_by_xpath("//div[contains(@class, 'level-item')]//h1")
for i in range(len(a)):
print(a[i].get_attribute("innerText"))
print(b[i].get_attribute("innerText"))
print(c[i].get_attribute("innerText"))
Confirmed + 25,136 2,23,21,229
Active 37,42,119
Recovered + 15,165 1,83,26,851
Deceased + 313 2,42,712
You will need to rearrange the code!
Upvotes: 1
Reputation: 3400
NO need of .
requires in xpath
due to that it can't find the location of element
from selenium import webdriver
from time import sleep
from selenium.webdriver.support import expected_conditions as EC
PATH = 'C:\Program Files (x86)\chromedriver.exe'
driver = webdriver.Chrome(PATH)
driver.get('https://www.covid19india.org/')
sleep(5)
daily=driver.find_element_by_xpath('//*[@id="root"]/div/div[2]/div[1]/div[2]/div[2]/div[1]/h4').text
confirmed=driver.find_element_by_xpath('//*[@id="root"]/div/div[2]/div[1]/div[2]/div[2]/div[1]/h1').text
print(daily)
print(confirmed)
Output:
+ 11,155
2,23,07,248
Upvotes: 1
Reputation: 33351
Level
so you should use find_element_by_class_name
instead of find_elements_by_class_name
to locate it.confirmed
list..//*[@id="root"]/div/div[2]/div[1]/div[2]/div[1]/div[1]/h4
or by .//*[@id="root"]/div/div[2]/div[1]/div[2]/div[1]/div[1]/h1
below the element located by Level
class name thereUpvotes: 1