最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

spotify - File not found, python code can read the file yet gave a file not found message - Stack Overflow

programmeradmin0浏览0评论

Platform: ThinkPAD laptop / windows11 / Microsoft Visual Studio Code

Python version: Python 3.13.1

I was trying to download tracks from Spotify Music, I got all the album links stored in a text file. I hope the following code will download all the tracks, the links of which is stored in the urls.txt file.

import subprocess
import os
import time
import re
from spotipy import Spotify
from spotipy.oauth2 import SpotifyClientCredentials

def get_album_tracks(album_url, spotify_client):
    """Retrieve all track URLs from an album URL."""
    try:
        # Extract album ID from the URL
        match = re.match(r"https?://open\.spotify\/album/([a-zA-Z0-9]+)", album_url)
        if not match:
            print(f"Invalid album URL: {album_url}")
            return []

        album_id = match.group(1)

        # Fetch album tracks
        tracks = spotify_client.album_tracks(album_id)
        track_links = [track['external_urls']['spotify'] for track in tracks['items']]

        return track_links
    except Exception as e:
        print(f"Error retrieving tracks for album {album_url}: {e}")
        return []

def download_songs_from_file(file_path, download_directory, client_id, client_secret, max_retries=3):
    try:
        # Ensure the download directory exists
        os.makedirs(download_directory, exist_ok=True)

        # Authenticate with Spotify API
        spotify_client = Spotify(client_credentials_manager=SpotifyClientCredentials(client_id, client_secret))

        # Read album links from the file
        with open(file_path, 'r') as file:
            album_links = [link.strip() for link in file if link.strip()]  # Remove empty lines and whitespace

        total_albums = len(album_links)
        total_tracks = 0
        successful_downloads = 0

        print(f"Total albums to process: {total_albums}")

        for album_index, album_link in enumerate(album_links, start=1):
            print(f"\nProcessing album ({album_index}/{total_albums}): {album_link}")

            # Get all track links from the album
            track_links = get_album_tracks(album_link, spotify_client)
            track_count = len(track_links)
            total_tracks += track_count

            print(f"Found {track_count} tracks in album: {album_link}")

            for track_index, track_link in enumerate(track_links, start=1):
                print(f"Downloading track ({track_index}/{track_count}): {track_link}")
                retries = 0
                while retries < max_retries:
                    try:
                        # Run the spotdl command
                        subprocess.run(
                            ["spotdl", "download", track_link, "--path", download_directory],
                            check=True
                        )
                        print(f"Downloaded successfully: {track_link}")
                        successful_downloads += 1
                        break
                    except subprocess.CalledProcessError as e:
                        retries += 1
                        print(f"Error downloading: {track_link} (Attempt {retries}/{max_retries}) - {e}")
                        if retries >= max_retries:
                            print(f"Skipping after {max_retries} attempts.")
                        else:
                            time.sleep(2)  # Short delay before retrying

        # Count the actual files in the download directory
        downloaded_files = len([f for f in os.listdir(download_directory) if os.path.isfile(os.path.join(download_directory, f))])

        print(f"\nDownload summary:")
        print(f"Total albums in list: {total_albums}")
        print(f"Total tracks found: {total_tracks}")
        print(f"Successfully downloaded: {successful_downloads}")
        print(f"Failed downloads: {total_tracks - successful_downloads}")
        print(f"Total files in '{download_directory}': {downloaded_files}")

    except FileNotFoundError:
        print(f"The file {file_path} was not found.")
    except Exception as e:
        print(f"An error occurred: {e}")

# Example usage
file_path = "C:\\Users\\myname\\Music\\BEYOND\\urls.txt"  # File containing album links
download_directory = "C:\\Users\\myname\\Music\\BEYOND"  # Directory for downloads
client_id = "my_client_id"  # Spotify API Client ID
client_secret = "my_client_sectet"  # Spotify API Client Secret

download_songs_from_file(file_path, download_directory, client_id, client_secret)

The output:

Processing album (1/50): 
Found 12 tracks in album: 
Downloading track (1/12): 
The file C:\Users\myname\Music\BEYOND\urls.txt was not found.

One thing clear is that the code already read the file, right?

But why it gave the file not found message?

Any advice to correct/improve this code will be highly appreciated.

Thanks!

Platform: ThinkPAD laptop / windows11 / Microsoft Visual Studio Code

Python version: Python 3.13.1

I was trying to download tracks from Spotify Music, I got all the album links stored in a text file. I hope the following code will download all the tracks, the links of which is stored in the urls.txt file.

import subprocess
import os
import time
import re
from spotipy import Spotify
from spotipy.oauth2 import SpotifyClientCredentials

def get_album_tracks(album_url, spotify_client):
    """Retrieve all track URLs from an album URL."""
    try:
        # Extract album ID from the URL
        match = re.match(r"https?://open\.spotify\.com/album/([a-zA-Z0-9]+)", album_url)
        if not match:
            print(f"Invalid album URL: {album_url}")
            return []

        album_id = match.group(1)

        # Fetch album tracks
        tracks = spotify_client.album_tracks(album_id)
        track_links = [track['external_urls']['spotify'] for track in tracks['items']]

        return track_links
    except Exception as e:
        print(f"Error retrieving tracks for album {album_url}: {e}")
        return []

def download_songs_from_file(file_path, download_directory, client_id, client_secret, max_retries=3):
    try:
        # Ensure the download directory exists
        os.makedirs(download_directory, exist_ok=True)

        # Authenticate with Spotify API
        spotify_client = Spotify(client_credentials_manager=SpotifyClientCredentials(client_id, client_secret))

        # Read album links from the file
        with open(file_path, 'r') as file:
            album_links = [link.strip() for link in file if link.strip()]  # Remove empty lines and whitespace

        total_albums = len(album_links)
        total_tracks = 0
        successful_downloads = 0

        print(f"Total albums to process: {total_albums}")

        for album_index, album_link in enumerate(album_links, start=1):
            print(f"\nProcessing album ({album_index}/{total_albums}): {album_link}")

            # Get all track links from the album
            track_links = get_album_tracks(album_link, spotify_client)
            track_count = len(track_links)
            total_tracks += track_count

            print(f"Found {track_count} tracks in album: {album_link}")

            for track_index, track_link in enumerate(track_links, start=1):
                print(f"Downloading track ({track_index}/{track_count}): {track_link}")
                retries = 0
                while retries < max_retries:
                    try:
                        # Run the spotdl command
                        subprocess.run(
                            ["spotdl", "download", track_link, "--path", download_directory],
                            check=True
                        )
                        print(f"Downloaded successfully: {track_link}")
                        successful_downloads += 1
                        break
                    except subprocess.CalledProcessError as e:
                        retries += 1
                        print(f"Error downloading: {track_link} (Attempt {retries}/{max_retries}) - {e}")
                        if retries >= max_retries:
                            print(f"Skipping after {max_retries} attempts.")
                        else:
                            time.sleep(2)  # Short delay before retrying

        # Count the actual files in the download directory
        downloaded_files = len([f for f in os.listdir(download_directory) if os.path.isfile(os.path.join(download_directory, f))])

        print(f"\nDownload summary:")
        print(f"Total albums in list: {total_albums}")
        print(f"Total tracks found: {total_tracks}")
        print(f"Successfully downloaded: {successful_downloads}")
        print(f"Failed downloads: {total_tracks - successful_downloads}")
        print(f"Total files in '{download_directory}': {downloaded_files}")

    except FileNotFoundError:
        print(f"The file {file_path} was not found.")
    except Exception as e:
        print(f"An error occurred: {e}")

# Example usage
file_path = "C:\\Users\\myname\\Music\\BEYOND\\urls.txt"  # File containing album links
download_directory = "C:\\Users\\myname\\Music\\BEYOND"  # Directory for downloads
client_id = "my_client_id"  # Spotify API Client ID
client_secret = "my_client_sectet"  # Spotify API Client Secret

download_songs_from_file(file_path, download_directory, client_id, client_secret)

The output:

Processing album (1/50): https://open.spotify.com/album/6oGvml3VgdRhNCTRX32Tbs
Found 12 tracks in album: https://open.spotify.com/album/6oGvml3VgdRhNCTRX32Tbs
Downloading track (1/12): https://open.spotify.com/track/466cmnbIuOeQ3aKpijfvmf
The file C:\Users\myname\Music\BEYOND\urls.txt was not found.

One thing clear is that the code already read the file, right?

But why it gave the file not found message?

Any advice to correct/improve this code will be highly appreciated.

Thanks!

Share Improve this question asked Jan 19 at 11:51 beesunsbeesuns 211 silver badge7 bronze badges 2
  • 1 Note that the print after subprocess.run was not executed, so probably the error is within this line. Maybe printing all the trace error will show you what is really happening. – Iran Ribeiro Commented Jan 19 at 12:23
  • 1 It's a Bad Idea to assume where/why/how your exception is thrown. If you'd logged the actual exception with stack trace instead of flattening it down to a specific error message (assuming, incorrectly, that file_path is the thing the exception referred to as not being findable) then you wouldn't have needed to come here in the first place. – Charles Duffy Commented Jan 19 at 12:50
Add a comment  | 

1 Answer 1

Reset to default 0

subprocess.run without argument shell=True tries to run your application without a shell and if the app is not found, it will throw FileNotFound as essentially your python code doesn't know where to find it. See:

>>> subprocess.run(["spotydl"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python312\Lib\subprocess.py", line 548, in run
    with Popen(*popenargs, **kwargs) as process:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\subprocess.py", line 1026, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Python312\Lib\subprocess.py", line 1538, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [WinError 2] The system cannot find the file specified
>>>

versus with shell:

>>> subprocess.run(["spotydl"], shell=True)
'spotydl' is not recognized as an internal or external command,
operable program or batch file.
CompletedProcess(args=['spotydl'], returncode=1)
>>>

So, the issue is that your subprocess call doesnt find spotdl. I'd just use absolute path to the spotdl executable to fix this.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论