Spaces:
Runtime error
Runtime error
| import re | |
| import requests | |
| def resolve_spotify_track(url: str) -> dict: | |
| """ | |
| Scrapes a public Spotify track page to extract the song title and artist. | |
| Returns: {"title": str, "artist": str} or None if resolution fails. | |
| """ | |
| # Regex to extract track ID | |
| match = re.search(r"track/([a-zA-Z0-9]+)", url) | |
| if not match: | |
| return None | |
| headers = { | |
| "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" | |
| } | |
| try: | |
| response = requests.get(url, headers=headers, timeout=10) | |
| if response.status_code != 200: | |
| return None | |
| html = response.text | |
| # Try og:title and og:description or title tag | |
| # og:title typically has the song title | |
| title_match = re.search(r'<meta\s+property="og:title"\s+content="([^"]+)"', html) | |
| # og:description or twitter:description usually has "Song 路 Artist 路 Year" or "Artist 路 Song" | |
| desc_match = re.search(r'<meta\s+(?:property|name)="(?:og|twitter):description"\s+content="([^"]+)"', html) | |
| title = None | |
| artist = None | |
| if title_match: | |
| title = title_match.group(1).strip() | |
| if desc_match: | |
| desc = desc_match.group(1).strip() | |
| # If desc looks like "Song 路 Artist 路 Year" or similar | |
| parts = [p.strip() for p in desc.split("路")] | |
| if len(parts) >= 2: | |
| # Often: "Song 路 Artist 路 Year" or "Artist 路 Song 路 [etc]" | |
| # Let's verify which one is the title. | |
| # If the first part matches the og:title, then the second part is the artist! | |
| if title and parts[0].lower() == title.lower(): | |
| artist = parts[1] | |
| elif title and parts[1].lower() == title.lower(): | |
| artist = parts[0] | |
| else: | |
| artist = parts[1] | |
| else: | |
| # Fallback: check if description says "Listen to [Song] on Spotify. [Artist] 路 Song 路 [Year]" | |
| listen_match = re.search(r"Listen to\s+([^\s]+)\s+on Spotify\.\s+([^\路]+)", desc) | |
| if listen_match: | |
| artist = listen_match.group(2).strip() | |
| # If still not found, try a simple title parse | |
| if not title: | |
| html_title = re.search(r"<title>([^<]+)</title>", html) | |
| if html_title: | |
| t_content = html_title.group(1) | |
| # Usually: "Song Name - song and artist by Artist | Spotify" | |
| t_parts = t_content.split(" | ") | |
| if len(t_parts) > 0: | |
| title = t_parts[0].replace(" - song and artist by ", " - ") | |
| # Clean up common spotify suffix / prefix | |
| if title: | |
| title = re.sub(r"\s-\s.*$", "", title) # remove everything after " - " | |
| if not title: | |
| return None | |
| return { | |
| "title": title, | |
| "artist": artist or "Unknown Artist" | |
| } | |
| except Exception as e: | |
| print(f"Error resolving Spotify metadata: {e}") | |
| return None | |
| # Simple testing hook | |
| if __name__ == "__main__": | |
| test_url = "https://open.spotify.com/track/4PTG3Z6ehGkBF3zI7YSpA0" | |
| print(resolve_spotify_track(test_url)) | |