diff --git a/beatport_unified_scraper.py b/beatport_unified_scraper.py index 0b3c8eb2..ed039009 100644 --- a/beatport_unified_scraper.py +++ b/beatport_unified_scraper.py @@ -1284,6 +1284,125 @@ class BeatportUnifiedScraper: print(f" ā Error converting track data: {e}") return None + def scrape_homepage_top10_lists(self) -> Dict[str, List[Dict]]: + """Scrape Top 10 Lists from homepage - Beatport Top 10 and Hype Top 10""" + print("\nš Scraping Top 10 Lists from homepage...") + + soup = self.get_page(self.base_url) + if not soup: + return {"beatport_top10": [], "hype_top10": []} + + # Extract Beatport Top 10 tracks + beatport_top10_items = soup.select('[data-testid="top-10-item"]') + print(f" Found {len(beatport_top10_items)} Beatport Top 10 items") + + beatport_tracks = [] + for i, item in enumerate(beatport_top10_items, 1): + try: + track_data = self.extract_track_from_top10_item(item, i, "Beatport Top 10") + if track_data: + beatport_tracks.append(track_data) + except Exception as e: + print(f" ā Error extracting Beatport track {i}: {e}") + + # Extract Hype Top 10 tracks + hype_top10_items = soup.select('[data-testid="hype-top-10-item"]') + print(f" Found {len(hype_top10_items)} Hype Top 10 items") + + hype_tracks = [] + for i, item in enumerate(hype_top10_items, 1): + try: + track_data = self.extract_track_from_top10_item(item, i, "Hype Top 10") + if track_data: + hype_tracks.append(track_data) + except Exception as e: + print(f" ā Error extracting Hype track {i}: {e}") + + print(f"ā Extracted {len(beatport_tracks)} Beatport Top 10 + {len(hype_tracks)} Hype Top 10 tracks") + + return { + "beatport_top10": beatport_tracks, + "hype_top10": hype_tracks + } + + def extract_track_from_top10_item(self, item, rank, list_name): + """Extract track data from a top 10 list item""" + try: + # Get the track URL + link_elem = item.select_one('a[href*="/track/"]') + track_url = "" + if link_elem and link_elem.get('href'): + track_url = f"https://www.beatport.com{link_elem.get('href')}" + + # Extract track title + title = "Unknown Title" + title_selectors = [ + '[class*="ItemName"]', + '[class*="TrackName"]', + '[class*="track-name"]', + 'a[href*="/track/"]' + ] + + for selector in title_selectors: + title_elem = item.select_one(selector) + if title_elem: + title = title_elem.get_text(strip=True) + if title and title != "Unknown Title": + break + + # Extract artist name + artist = "Unknown Artist" + artist_selectors = [ + '[class*="Artists"]', + '[class*="artist"]', + '[class*="Artist"]', + '[class*="ItemArtist"]', + 'a[href*="/artist/"]' + ] + + for selector in artist_selectors: + artist_elem = item.select_one(selector) + if artist_elem: + artist = artist_elem.get_text(strip=True) + if artist and artist != "Unknown Artist": + break + + # Extract label name + label = "Unknown Label" + label_selectors = [ + '[class*="Label"]', + '[class*="label"]', + '[class*="ItemLabel"]', + 'a[href*="/label/"]' + ] + + for selector in label_selectors: + label_elem = item.select_one(selector) + if label_elem: + label = label_elem.get_text(strip=True) + if label and label != "Unknown Label": + break + + # Extract artwork if available + artwork_url = "" + img_elem = item.select_one('img') + if img_elem and img_elem.get('src'): + artwork_url = img_elem.get('src') + + return { + "rank": rank, + "title": title, + "artist": artist, + "label": label, + "url": track_url, + "artwork_url": artwork_url, + "list_name": list_name + } + + except Exception as e: + print(f"Error extracting track data: {e}") + return None + def scrape_new_on_beatport_hero(self, limit: int = 10) -> List[Dict]: """Scrape the 'New on Beatport' hero slideshow from homepage""" print("\nšÆ Scraping 'New on Beatport' hero slideshow...") diff --git a/web_server.py b/web_server.py index 72145ceb..2a97b8aa 100644 --- a/web_server.py +++ b/web_server.py @@ -13228,6 +13228,40 @@ def get_beatport_homepage_top_10_releases(): "track_count": 0 }), 500 +@app.route('/api/beatport/homepage/top-10-lists', methods=['GET']) +def get_beatport_homepage_top10_lists(): + """Get Beatport Top 10 Lists from homepage - both Beatport Top 10 and Hype Top 10""" + try: + logger.info("š API request for Beatport homepage Top 10 Lists") + + # Initialize the Beatport scraper + scraper = BeatportUnifiedScraper() + + # Get top 10 lists from homepage + top10_lists = scraper.scrape_homepage_top10_lists() + + logger.info(f"ā Successfully extracted Beatport Top 10: {len(top10_lists['beatport_top10'])}, Hype Top 10: {len(top10_lists['hype_top10'])}") + + return jsonify({ + "success": True, + "beatport_top10": top10_lists["beatport_top10"], + "hype_top10": top10_lists["hype_top10"], + "beatport_count": len(top10_lists["beatport_top10"]), + "hype_count": len(top10_lists["hype_top10"]), + "source": "beatport_homepage_top10_lists" + }) + + except Exception as e: + logger.error(f"ā Error getting Beatport homepage top 10 lists: {e}") + return jsonify({ + "success": False, + "error": str(e), + "beatport_top10": [], + "hype_top10": [], + "beatport_count": 0, + "hype_count": 0 + }), 500 + @app.route('/api/beatport/homepage/featured-charts', methods=['GET']) def get_beatport_homepage_featured_charts(): """Get Beatport Featured Charts from homepage section""" diff --git a/webui/index.html b/webui/index.html index 60b47c8f..3e66cf4e 100644 --- a/webui/index.html +++ b/webui/index.html @@ -806,6 +806,50 @@ + +
Current trending tracks from Beatport charts
+Most popular tracks on Beatport
+Fetching trending tracks
+Editor's hottest trending picks
+Fetching editor's picks
+Most popular tracks on Beatport
+${track.artist || 'Unknown Artist'}
+${track.label || 'Unknown Label'}
+Editor's trending picks
+${track.artist || 'Unknown Artist'}
+${track.label || 'Unknown Label'}
+${errorMessage}
+