rapformer / scraper.py
z66x
final scraper
5cf9a7b
Raw
History Blame Contribute Delete
3.52 kB
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()
# Pre-load the tracker with any songs downloaded on previous days
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 # Counter only goes up on successful save
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)
# Explicitly state it was ADDED
print(f"[{artist_name}] Added {saved_count} | Title: '{song.title}'")
else:
print(f"[{artist_name}] -> Skipped '{song.title}': Lyrics too short after cleaning.")
else:
# Explicitly state WHICH song was skipped
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.")