Home > Net >  How to skip over an item in a list when using a for loop
How to skip over an item in a list when using a for loop

Time:10-29

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.

  • Related