Python爬取KKBox榜单内容为空,如何获取歌曲、艺人及排名信息?
解决KKBox榜单爬取空标签问题
问题原因
该页面的榜单数据是通过JavaScript动态加载的,requests库只能获取页面的初始静态HTML,此时目标标签还未被JS填充内容,所以返回空标签。
解决方案一:使用Selenium模拟浏览器渲染
Selenium可以模拟真实浏览器加载页面,等待JS执行完成后再获取渲染后的完整内容。
实现步骤:
- 安装Selenium库及对应浏览器驱动(如ChromeDriver,需与浏览器版本匹配)
- 编写代码模拟浏览器访问、等待数据加载,再提取目标信息
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time from bs4 import BeautifulSoup # 初始化Chrome浏览器驱动(确保驱动路径正确) driver = webdriver.Chrome() driver.get('https://kma.kkbox.com/charts/weekly/newrelease?terr=my&lang=en') try: # 等待榜单元素加载完成,超时时间10秒 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "charts-list-song")) ) # 额外等待2秒确保所有数据渲染完成 time.sleep(2) # 获取渲染后的页面源码 page_source = driver.page_source soup = BeautifulSoup(page_source, 'html.parser') # 提取并格式化输出榜单数据 chart_items = soup.find_all(class_="charts-list-item") print(f"{'Pos':<4} {'artist':<20} {'songs'}") for idx, item in enumerate(chart_items, 1): song = item.find(class_="charts-list-song").get_text(strip=True) artist = item.find(class_="charts-list-artist").get_text(strip=True) print(f"{idx:<4} {artist:<20} {song}") finally: # 关闭浏览器 driver.quit()
解决方案二:直接调用API接口(更高效)
通过浏览器开发者工具的Network面板,可找到页面加载时获取榜单数据的XHR请求,直接调用该API获取JSON格式的原始数据,无需模拟浏览器渲染。
示例代码:
import requests # 抓包获取的API接口(注意:接口可能随网站更新变化) api_url = "https://kma.kkbox.com/api/v1/charts/weekly/newrelease?terr=my&lang=en&limit=100" # 设置请求头,模拟浏览器请求避免被拦截 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", "Referer": "https://kma.kkbox.com/charts/weekly/newrelease?terr=my&lang=en" } response = requests.get(api_url, headers=headers) if response.status_code == 200: data = response.json() print(f"{'Pos':<4} {'artist':<20} {'songs'}") for idx, entry in enumerate(data['data']['tracks'], 1): artist_name = entry['artist']['name'] song_name = entry['name'] print(f"{idx:<4} {artist_name:<20} {song_name}") else: print(f"请求失败,状态码:{response.status_code}")
注意:API接口可能会被网站修改或添加验证机制,若失效需重新通过开发者工具抓包获取最新接口。
内容的提问来源于stack exchange,提问作者Hi Hi try
相关产品推荐
相关产品推荐

