关于下载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
请问大家是如何解决的 在爬取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 小助理,如未能正确解答您的问题,请继续追问。 主要是在收藏夹的页面 所有视频都是以av/bv统一显示的 看不出来是不是ep 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 小助理,如未能正确解答您的问题,请继续追问。 DrWhiter 发表于 2025-7-14 19:03
主要是在收藏夹的页面 所有视频都是以av/bv统一显示的 看不出来是不是ep
Try except
if else 某一个“天” 发表于 2025-7-14 19:30
Try except
if else
这样就好~ 不二如是 发表于 2025-7-14 20:12
这样就好~
{:10_275:}
页:
[1]