You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python爬取KKBox榜单内容为空,如何获取歌曲、艺人及排名信息?

解决KKBox榜单爬取空标签问题

问题原因

该页面的榜单数据是通过JavaScript动态加载的,requests库只能获取页面的初始静态HTML,此时目标标签还未被JS填充内容,所以返回空标签。

解决方案一:使用Selenium模拟浏览器渲染

Selenium可以模拟真实浏览器加载页面,等待JS执行完成后再获取渲染后的完整内容。

实现步骤:

  1. 安装Selenium库及对应浏览器驱动(如ChromeDriver,需与浏览器版本匹配)
  2. 编写代码模拟浏览器访问、等待数据加载,再提取目标信息
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:31:04