鱼C论坛

 找回密码
 立即注册
查看: 47|回复: 6

关于下载b站视频

[复制链接]
发表于 昨天 18:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在爬取B站收藏夹时发现的问题
一部分收藏夹的视频是以.com/bangumi/   play/ep1914706而非".com/    video/BVxxxxxxx"这种形式被访问
而我用来爬取b站视频的代码如下所示:
  1. def download_audio(bvid, folder):
  2.     response = requests.get(url=f'https://
复制代码

这样的话遇到如上那种形式的时候往往会报错 list index out of range
请问大家是如何解决的
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 19:00 | 显示全部楼层
在爬取B站收藏夹时遇到番剧链接(`/bangumi/play/ep`)导致报错,这是因为你的代码只能处理普通视频链接(`/video/BV`)。以下是解决方案:

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

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

  1. import re
  2. import requests

  3. def extract_bvid(url):
  4.     # 普通视频链接处理 (BV号)
  5.     if "/video/BV" in url:
  6.         match = re.search(r"/video/(BV[0-9A-Za-z]+)", url)
  7.         return match.group(1) if match else None
  8.    
  9.     # 番剧链接处理 (ep号转BV号)
  10.     elif "/bangumi/play/ep" in url:
  11.         ep_id = re.search(r"ep(\d+)", url).group(1)
  12.         api_url = f"[url=https://api.bilibili.com/pgc/view/web/season?ep_id={ep_id}"]https://api.bilibili.com/pgc/view/web/season?ep_id={ep_id}"[/url]
  13.         
  14.         resp = requests.get(
  15.             api_url,
  16.             headers={"User-Agent": "Mozilla/5.0"},
  17.             cookies={"SESSDATA": "你的SESSDATA(可选)"}  # 需要登录时添加
  18.         )
  19.         
  20.         if resp.status_code == 200:
  21.             data = resp.json()
  22.             # 从API返回的剧集列表中匹配当前ep_id
  23.             for episode in data["result"]["episodes"]:
  24.                 if str(episode["id"]) == ep_id:
  25.                     return episode["bvid"]
  26.     return None  # 非视频链接
复制代码


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

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

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

  3. for url in video_urls:
  4.     bvid = extract_bvid(url)
  5.     if bvid:
  6.         download_audio(bvid, "下载文件夹")
  7.     else:
  8.         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 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 19:03 | 显示全部楼层
主要是在收藏夹的页面 所有视频都是以av/bv统一显示的 看不出来是不是ep
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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


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

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

  1. import requests
  2. import json

  3. def get_favorites(fid, cookie):
  4.     """获取收藏夹内所有视频的真实BV号"""
  5.     api_url = f"https://api.bilibili.com/x/v3/fav/resource/list?media_id={fid}&ps=20"
  6.     headers = {
  7.         "User-Agent": "Mozilla/5.0",
  8.         "Cookie": cookie  # 需要有效cookies
  9.     }
  10.    
  11.     bv_list = []
  12.     pn = 1
  13.     while True:
  14.         resp = requests.get(f"{api_url}&pn={pn}", headers=headers)
  15.         data = resp.json().get('data', {})
  16.         
  17.         # 提取所有视频的BV号
  18.         for item in data.get('medias', []):
  19.             bvid = item.get('bvid')
  20.             if bvid:
  21.                 bv_list.append(bvid)
  22.         
  23.         # 检查是否还有下一页
  24.         if data.get('has_more') != 1:
  25.             break
  26.         pn += 1
  27.    
  28.     return bv_list

  29. # 使用示例
  30. cookie = "SESSDATA=你的SESSDATA;"
  31. favorites_id = "收藏夹ID"  # 在收藏夹URL中找到
  32. 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列表**:
  
  1. bv_list = get_favorites("1234567", "SESSDATA=abc123...")
  2.    for bvid in bv_list:
  3.        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. **错误处理**:
  
  1. try:
  2.        resp = requests.get(...)
  3.        resp.raise_for_status()
  4.    except requests.exceptions.RequestException as e:
  5.        print(f"请求失败: {e}")
复制代码


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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

Try except
if else
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 20:12 | 显示全部楼层

这样就好~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 21:21 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-15 02:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表