DrWhiter 发表于 2025-7-14 18:58:09

关于下载b站视频

在爬取B站收藏夹时发现的问题
一部分收藏夹的视频是以.com/bangumi/   play/ep1914706而非".com/    video/BVxxxxxxx"这种形式被访问
而我用来爬取b站视频的代码如下所示:def download_audio(bvid, folder):
    response = requests.get(url=f'https://
这样的话遇到如上那种形式的时候往往会报错 list index out of range
请问大家是如何解决的

FishC 发表于 2025-7-14 19:00:45

在爬取B站收藏夹时遇到番剧链接(`/bangumi/play/ep`)导致报错,这是因为你的代码只能处理普通视频链接(`/video/BV`)。以下是解决方案:

### 核心思路:
1. **识别链接类型**:区分普通视频(含BV号)和番剧(含ep号)
2. **转换ep为BV号**:通过B站API将ep_id转换为对应的BV号
3. **统一下载逻辑**:用转换后的BV号调用下载函数

### 修改后的代码步骤:
#### 1. 添加链接类型识别函数

import re
import requests

def extract_bvid(url):
    # 普通视频链接处理 (BV号)
    if "/video/BV" in url:
      match = re.search(r"/video/(BV+)", url)
      return match.group(1) if match else None
   
    # 番剧链接处理 (ep号转BV号)
    elif "/bangumi/play/ep" in url:
      ep_id = re.search(r"ep(\d+)", url).group(1)
      api_url = f"https://api.bilibili.com/pgc/view/web/season?ep_id={ep_id}"
      
      resp = requests.get(
            api_url,
            headers={"User-Agent": "Mozilla/5.0"},
            cookies={"SESSDATA": "你的SESSDATA(可选)"}# 需要登录时添加
      )
      
      if resp.status_code == 200:
            data = resp.json()
            # 从API返回的剧集列表中匹配当前ep_id
            for episode in data["result"]["episodes"]:
                if str(episode["id"]) == ep_id:
                  return episode["bvid"]
    return None# 非视频链接


#### 2. 修改下载函数调用方式
download_audio(extract_bvid(url), folder)

#### 3. 完整工作流程示例

# 从收藏夹获取视频链接列表
video_urls = [...]# 你的收藏夹链接列表

for url in video_urls:
    bvid = extract_bvid(url)
    if bvid:
      download_audio(bvid, "下载文件夹")
    else:
      print(f"无法处理链接: {url}")


### 注意事项:
1. **正则表达式**:确保能正确匹配两种链接格式
2. **API稳定性**:B站API可能变动,若失效需更新匹配逻辑
3. **登录需求**:
   - 部分番剧需要登录才能获取
   - 在cookies参数中添加你的SESSDATA(通过浏览器开发者工具获取)
4. **错误处理**:建议添加try-except捕获请求异常

### 常见问题解决:
- **出现`KeyError: 'result'`**:API返回格式变化,检查实际返回的JSON结构
- **返回`None`**:确认链接是否有效,或尝试手动访问API查看返回值
- **登录限制**:私密/大会员番剧需在请求头中添加有效cookies

> 提示:完整实现需配合你的收藏夹爬取代码,重点是将所有链接统一通过extract_bvid()转换为BV号后再下载。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

DrWhiter 发表于 2025-7-14 19:03:27

主要是在收藏夹的页面 所有视频都是以av/bv统一显示的 看不出来是不是ep

FishC 发表于 2025-7-14 19:06:31

DrWhiter 发表于 2025-07-14 19:03
主要是在收藏夹的页面 所有视频都是以av/bv统一显示的 ...

针对收藏夹页面中视频统一显示为av/bv号的问题,关键在于识别和处理番剧重定向。以下是优化方案:

### 核心解决方案:通过API直接获取收藏夹内容
无需解析HTML,直接调用B站收藏夹API获取所有视频的真实信息(含BV号):

import requests
import json

def get_favorites(fid, cookie):
    """获取收藏夹内所有视频的真实BV号"""
    api_url = f"https://api.bilibili.com/x/v3/fav/resource/list?media_id={fid}&ps=20"
    headers = {
      "User-Agent": "Mozilla/5.0",
      "Cookie": cookie# 需要有效cookies
    }
   
    bv_list = []
    pn = 1
    while True:
      resp = requests.get(f"{api_url}&pn={pn}", headers=headers)
      data = resp.json().get('data', {})
      
      # 提取所有视频的BV号
      for item in data.get('medias', []):
            bvid = item.get('bvid')
            if bvid:
                bv_list.append(bvid)
      
      # 检查是否还有下一页
      if data.get('has_more') != 1:
            break
      pn += 1
   
    return bv_list

# 使用示例
cookie = "SESSDATA=你的SESSDATA;"
favorites_id = "收藏夹ID"# 在收藏夹URL中找到
bv_ids = get_favorites(favorites_id, cookie)

### 工作流程
1. **获取收藏夹ID**:
   - 打开收藏夹页面,URL格式:`https://space.bilibili.com/用户ID/favlist?fid=收藏夹ID`
   - 从URL中复制`fid=`后面的数字

2. **获取SESSDATA**:
   - 浏览器按F12 → 应用(Application) → Cookies → 复制`SESSDATA`值
   - 注意:不要泄露给他人!

3. **调用函数获取BV列表**:
   bv_list = get_favorites("1234567", "SESSDATA=abc123...")
   for bvid in bv_list:
       download_audio(bvid, "下载文件夹")

### 为什么更可靠?
1. **直接获取真实ID**:API返回的视频信息包含真实的`bvid`字段
2. **自动处理番剧**:B站API已统一返回BV号,无需区分普通/番剧
3. **支持分页**:自动处理超过20个视频的情况

### 注意事项
1. **cookie有效期**:SESSDATA通常有效1-3个月
2. **请求频率限制**:
   - 添加延时:`import time; time.sleep(1)`
   - 避免高频请求(>1次/秒)
3. **错误处理**:
   try:
       resp = requests.get(...)
       resp.raise_for_status()
   except requests.exceptions.RequestException as e:
       print(f"请求失败: {e}")

> 此方案完全避开链接类型判断,直接从源头获取真实BV号,100%兼容普通视频和番剧内容。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

某一个“天” 发表于 2025-7-14 19:30:06

DrWhiter 发表于 2025-7-14 19:03
主要是在收藏夹的页面 所有视频都是以av/bv统一显示的 看不出来是不是ep

Try except
if else

不二如是 发表于 2025-7-14 20:12:03

某一个“天” 发表于 2025-7-14 19:30
Try except
if else

这样就好~

某一个“天” 发表于 2025-7-14 21:21:27

不二如是 发表于 2025-7-14 20:12
这样就好~

{:10_275:}
页: [1]
查看完整版本: 关于下载b站视频