I am trying to skip over this item in a list because it creates an exception. I used try and except as well as an if statement but its still not working rather its ignoring my if statement. if I put my if statement in the exception I cant use continue because continue only works in a loop. is there a way around?
import time
from selenium import webdriver
import selenium
from selenium.webdriver.chrome import service
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd
#class scraperdata():
ser= Service("C:\Program Files (x86)\chromedriver.exe")
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(options=options,service=ser)
driver.get('https://soundcloud.com/jujubucks')
print(driver.title)
wait = WebDriverWait(driver,30)
wait.until(EC.element_to_be_clickable((By.ID,"onetrust-accept-btn-handler"))).click()
try:
i = 1
for _ in range(32):
song_contents = driver.find_element(By.XPATH, "//li[@class='soundList__item'][{}]".format(i))
driver.execute_script("arguments[0].scrollIntoView(true);",song_contents)
search = song_contents.find_element(By.XPATH, ".//a[contains(@class,'soundTitle__username')]/span").text
search_song = song_contents.find_element(By.XPATH, ".//a[contains(@class,'soundTitle__title')]/span").text
search_date = song_contents.find_element(By.XPATH, ".//time[contains(@class,'relativeTime')]/span").text
search_plays = song_contents.find_element(By.XPATH, ".//span[contains(@class,'sc-ministats-small')]/span").text
i =1
if search_plays == False:
continue
option ={
'Artist': search,
'Song_title': search_song,
'Date': search_date,
'Streams': search_plays
}
song_list = []
song_list.append(option)
df = pd.DataFrame(song_list)
print(df)
except Exception:
pass
driver.quit()
Exception
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "c:\Users\houst\.vscode\extensions\ms-python.python-2021.10.1365161279\pythonFiles\lib\python\debugpy\__main__.py", line 45, in <module>
cli.main()
File "c:\Users\houst\.vscode\extensions\ms-python.python-2021.10.1365161279\pythonFiles\lib\python\debugpy/..\debugpy\server\cli.py", line 444, in main
run()
File "c:\Users\houst\.vscode\extensions\ms-python.python-2021.10.1365161279\pythonFiles\lib\python\debugpy/..\debugpy\server\cli.py", line 285, in run_file
runpy.run_path(target_as_str, run_name=compat.force_str("__main__"))
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 268, in run_path
return _run_module_code(code, init_globals, run_name,
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 97, in _run_module_code
_run_code(code, mod_globals, init_globals,
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "c:\Users\houst\API\Scraper.py", line 34, in <module>
search_plays = song_contents.find_element(By.XPATH, ".//span[contains(@class,'sc-ministats-small')]/span").text
File "C:\Users\houst\Envs\Mach\lib\site-packages\selenium\webdriver\remote\webelement.py", line 718, in find_element
return self._execute(Command.FIND_CHILD_ELEMENT,
File "C:\Users\houst\Envs\Mach\lib\site-packages\selenium\webdriver\remote\webelement.py", line 693, in _execute
return self._parent.execute(command, params)
File "C:\Users\houst\Envs\Mach\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 418, in execute
self.error_handler.check_response(response)
File "C:\Users\houst\Envs\Mach\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 243, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":".//span[contains(@class,'sc-ministats-small')]/span"}
CodePudding user response:
import time
from selenium import webdriver
import selenium
from selenium.webdriver.chrome import service
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd
#class scraperdata():
ser= Service("C:\Program Files (x86)\chromedriver.exe")
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(options=options,service=ser)
driver.get('https://soundcloud.com/jujubucks')
print(driver.title)
wait = WebDriverWait(driver,30)
wait.until(EC.element_to_be_clickable((By.ID,"onetrust-accept-btn-handler"))).click()
i = 1
for _ in range(32):
try:
song_contents = driver.find_element(By.XPATH, "//li[@class='soundList__item'][{}]".format(i))
driver.execute_script("arguments[0].scrollIntoView(true);",song_contents)
search = song_contents.find_element(By.XPATH, ".//a[contains(@class,'soundTitle__username')]/span").text
search_song = song_contents.find_element(By.XPATH, ".//a[contains(@class,'soundTitle__title')]/span").text
search_date = song_contents.find_element(By.XPATH, ".//time[contains(@class,'relativeTime')]/span").text
search_plays = song_contents.find_element(By.XPATH, ".//span[contains(@class,'sc-ministats-small')]/span").text
i =1
if search_plays == False:
continue
option ={
'Artist': search,
'Song_title': search_song,
'Date': search_date,
'Streams': search_plays
}
song_list = []
song_list.append(option)
df = pd.DataFrame(song_list)
print(df)
except Exception:
pass
driver.quit()
Use try block inside the for loop, further you can put the desired part that has a tendency to pass an exception inside the try block. hope this helped.
CodePudding user response:
It's a good practice to only wrap the minimum lines that raise exceptions in your try
except
blocks.
In your traceback:
File "c:\Users\houst\API\Scraper.py", line 34, in <module>
search_plays = song_contents.find_element(By.XPATH, ".//span[contains(@class,'sc-ministats-small')]/span").text
You can see the exact line and number that is raising your exception.
Later on:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":".//span[contains(@class,'sc-ministats-small')]/span"}
You see the exact exception that is being raised.
for
loops have a built in mechanism for continuing on to the next iteration. The continue
statement.
Using this knowledge, you can wrap the offending line in a try
/except
and catch only the exception you care about. You would also need to import that exception first.
from selenium.common.exceptions import NoSuchElementException
try:
search_plays = song_contents.find_element(By.XPATH, ".//span[contains(@class,'sc-ministats-small')]/span").text
except NoSuchElementException:
continue
You can also modify your for
loop to iterate from 1
through 32
using range(1, 33)
. That way you don't need to manually increment i
.
Full code:
import time
from selenium import webdriver
import selenium
from selenium.webdriver.chrome import service
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
import pandas as pd
#class scraperdata():
ser = Service("C:\Program Files (x86)\chromedriver.exe")
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(options=options,service=ser)
driver.get('https://soundcloud.com/jujubucks')
print(driver.title)
wait = WebDriverWait(driver,30)
wait.until(EC.element_to_be_clickable((By.ID,"onetrust-accept-btn-handler"))).click()
for i in range(1, 33):
song_contents = driver.find_element(By.XPATH, "//li[@class='soundList__item'][{}]".format(i))
driver.execute_script("arguments[0].scrollIntoView(true);",song_contents)
search = song_contents.find_element(By.XPATH, ".//a[contains(@class,'soundTitle__username')]/span").text
search_song = song_contents.find_element(By.XPATH, ".//a[contains(@class,'soundTitle__title')]/span").text
search_date = song_contents.find_element(By.XPATH, ".//time[contains(@class,'relativeTime')]/span").text
try:
search_plays = song_contents.find_element(By.XPATH, ".//span[contains(@class,'sc-ministats-small')]/span").text
except NoSuchElementException:
continue
if search_plays == False:
continue
option ={
'Artist': search,
'Song_title': search_song,
'Date': search_date,
'Streams': search_plays
}
song_list = []
song_list.append(option)
df = pd.DataFrame(song_list)
print(df)
driver.quit()
CodePudding user response:
A for loop is not really designed for items to be skipped. Best to rewrite it using a while-loop.