| import os |
| import re |
| import json |
| import lyricsgenius |
|
|
| GENIUS_TOKEN = os.environ.get("GENIUS_TOKEN") |
|
|
| artists = [ |
| "Kanye West", "Kendrick Lamar", "Drake", "Eminem", |
| "Travis Scott", "J. Cole", "XXXTentacion", "NF" |
| ] |
|
|
| output_folder = "rap_dataset" |
| os.makedirs(output_folder, exist_ok=True) |
|
|
| def clean_lyrics(lyrics): |
| lyrics = re.sub(r'\[.*?\]', '', lyrics, flags=re.DOTALL) |
| lyrics = re.sub(r'\n{3,}', '\n\n', lyrics) |
| lyrics = re.sub(r'\d*[KM]?Embed$', '', lyrics) |
| return lyrics.strip() |
|
|
| genius = lyricsgenius.Genius( |
| GENIUS_TOKEN, |
| skip_non_songs=True, |
| excluded_terms=["(Remix)", "(Live)", "(Demo)"], |
| remove_section_headers=True, |
| timeout=15, |
| retries=3 |
| ) |
| genius.verbose = True |
|
|
| seen_songs = set() |
|
|
| |
| print("Scanning existing files for duplicates...") |
| for filename in os.listdir(output_folder): |
| if filename.endswith(".json"): |
| filepath = os.path.join(output_folder, filename) |
| try: |
| with open(filepath, "r", encoding="utf-8") as f: |
| existing_data = json.load(f) |
| for song in existing_data: |
| seen_songs.add(song["title"].lower().strip()) |
| except Exception as e: |
| print(f"Could not read {filename}: {e}") |
| |
| print(f"Memory loaded. Currently avoiding {len(seen_songs)} known duplicates.\n") |
|
|
|
|
| for artist_name in artists: |
| file_path = os.path.join(output_folder, f"{artist_name}.json") |
| if os.path.exists(file_path): |
| print(f"[{artist_name}] File already exists. Skipping.") |
| continue |
|
|
| print(f"[{artist_name}] Sending request to server for top 100 songs...") |
| try: |
| artist = genius.search_artist(artist_name, max_songs=100, sort="popularity") |
| |
| if artist: |
| total_songs = len(artist.songs) |
| print(f"[{artist_name}] Received response. Checking {total_songs} songs...") |
| |
| artist_dataset = [] |
| saved_count = 0 |
| |
| for song in artist.songs: |
| clean_title = song.title.lower().strip() |
| |
| if clean_title not in seen_songs and song.lyrics: |
| cleaned = clean_lyrics(song.lyrics) |
| if len(cleaned) > 100: |
| saved_count += 1 |
| artist_dataset.append({ |
| "artist": artist_name, |
| "title": song.title, |
| "lyrics": cleaned |
| }) |
| seen_songs.add(clean_title) |
| |
| |
| print(f"[{artist_name}] Added {saved_count} | Title: '{song.title}'") |
| else: |
| print(f"[{artist_name}] -> Skipped '{song.title}': Lyrics too short after cleaning.") |
| else: |
| |
| print(f"[{artist_name}] -> Skipped '{song.title}': Duplicate or missing lyrics.") |
|
|
| with open(file_path, "w", encoding="utf-8") as f: |
| json.dump(artist_dataset, f, indent=4) |
| |
| print(f"[{artist_name}] Successfully saved {saved_count} clean songs.\n") |
|
|
| except Exception as e: |
| print(f"[{artist_name}] ERROR: Something went wrong - {e}\n") |
| |
| print("Script finished.") |