使用 Python Selenium 和 Requests 实现歌曲网站批量下载实战

发布于:2025-08-14 ⋅ 阅读:(19) ⋅ 点赞:(0)

最近在爬取歌曲下载资源时,遇到一个有趣的挑战——歌曲宝网站的下载按钮触发弹窗,而且下载链接的访问需要调用后台接口确认“操作成功”,才能拿到真实的低品质MP3下载地址。为了实现批量自动下载,我结合 Selenium 模拟浏览器操作和 Requests 发送接口请求,写了一个完整的自动化脚本。今天分享下实现思路和关键点。


一、问题描述

该网站的周下载排行榜页面,歌曲列表在一个表格里,每首歌的详情页里有一个“下载歌曲”按钮。点击后弹出弹窗,用户需选择音质,低品质MP3链接是弹窗里的备用链接。

  • 直接用 Requests 请求弹窗页面拿不到下载链接
  • 弹窗的下载链接只有点击了一个后台接口 /api/ad-handle 后才有效
  • 真实的MP3下载链接在弹窗点击后打开新标签页,地址是CDN的mp3资源链接
  • 需要批量处理20页,每页10首歌

二、核心难点

  1. 弹窗异步加载和点击流程
    需要用 Selenium 模拟点击“下载歌曲”按钮,等待弹窗出现,点击“低品质MP3”链接,拿到真实的下载URL。

  2. 后台接口请求
    必须先调用 /api/ad-handle POST 接口,模拟广告播放确认,才能获得真实可用的下载链接。

  3. 保持请求状态和Cookie一致
    使用 Selenium 操作浏览器后,拿到的 Cookie 需要同步给 Requests,用于调用接口和下载 MP3,否则请求会被拒绝。


三、技术方案

  • 使用 Requests 来请求排行榜页面,解析出歌曲详情页URL。
  • 使用 Selenium(Chromedriver) 模拟浏览器打开歌曲详情页,执行点击操作,弹出音质选择弹窗。
  • 从 Selenium 获取 Cookie,传给 Requests,发送广告确认接口请求。
  • 弹窗中点击低品质MP3链接,切换标签页拿真实链接。
  • 用 Requests 下载 MP3 文件。

四、关键代码解读

1. Cookie 同步

def cookies_from_driver(driver):
    cookies = driver.get_cookies()
    cookie_dict = {}
    for cookie in cookies:
        cookie_dict[cookie['name']] = cookie['value']
    return cookie_dict

通过 Selenium 拿到浏览器的所有 Cookie,传给 Requests 保持会话一致。


2. 调用后端接口

def send_ad_handle(session, song_url, headers):
    api_url = "https://www.gequbao.com/api/ad-handle"
    post_headers = headers.copy()
    post_headers.update({
        'origin': 'https://www.gequbao.com',
        'referer': song_url,
        'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'x-requested-with': 'XMLHttpRequest',
    })
    data = ""
    resp = session.post(api_url, headers=post_headers, data=data)
    return resp.status_code == 200 and resp.json().get('code') == 1

这是成功获得下载授权的关键步骤。


3. 弹窗操作与真实链接获取

mp3_btn = wait.until(EC.element_to_be_clickable((By.ID, "btn-download-mp3")))
mp3_btn.click()

wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div.jconfirm-box")))
time.sleep(2)

low_quality_link = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.jconfirm-box a.default-link")))
low_quality_link.click()
time.sleep(2)

handles = driver.window_handles
if len(handles) > 1:
    driver.switch_to.window(handles[-1])
    mp3_url = driver.current_url
    driver.close()
    driver.switch_to.window(handles[0])
else:
    mp3_url = low_quality_link.get_attribute("href")

点击弹窗“低品质MP3”链接后,selenium自动切换到新标签页拿真实URL。


4. 批量爬取和下载

主循环里先解析排行榜页面,再逐个下载:

for page in range(1, PAGES + 1):
    url = BASE_URL.format(page)
    res = requests.get(url, headers=HEADERS)
    soup = BeautifulSoup(res.text, 'html.parser')
    table_div = soup.find('div', class_='table-responsive')
    links = table_div.find_all('a')

    for a in links:
        href = a.get('href')
        song_url = 'https://www.gequbao.com' + href
        song_title = a.text.strip()
        download_song(driver, session, song_url, song_title, SAVE_DIR)
        time.sleep(2)

五、使用说明

  • 需要安装 Python 库:selenium, requests, beautifulsoup4
  • 需要对应版本的 Chrome 浏览器和 chromedriver
  • 修改 PAGESSAVE_DIR 变量设置页数和保存目录
  • 脚本支持无头模式,调试时建议注释无头参数查看浏览器行为

六、总结

结合 Selenium 和 Requests,可以绕过传统纯爬虫难以处理的复杂页面交互和授权机制,实现真正的自动化批量下载。这个项目充分体现了自动化测试框架和HTTP请求库的协同优势。

如果你也遇到类似带弹窗授权的网页数据抓取,推荐用类似方法:

  • Selenium先浏览器交互
  • Requests补充接口调用和资源下载

完整代码放到了github:Marblog