Python中如何使用you-get从playlist中下载单独的视频?
b 站很多视频都是一个 playlist 的,you-get 解析 b 站的 url 只解析到 av 号,而忽略了后面的?p=**。
所以,you-get 只能解析到 playlist 中的第一个视频。
e.g. 这里解析 playlist 的
>you-get -i https://www.bilibili.com/video/av35557055?p=3
>you-get: This page contains a playlist. (use --playlist to download all videos.)
>site: Bilibili
>title: [ 1080 60 帧] 9 兔 8 蛋回归初舞台,IZONE 初 1 位! 181108 M!Countdown 女团 LIVE 现场合集 #3. >IZONE - La Vie en Rose
>streams: # Available quality and codecs
> [ DEFAULT ] _________________________________
> - format: hdflv
> container: flv
> size: 116.2 MiB (121878947 bytes)
> # download-with: you-get --format=hdflv [URL]
虽然 title 是对的,但从 size 可以看出依然是 playlist 中的第一个视频的。
可以看到有提示的参数使用:
This page contains a playlist. (use --playlist to download all videos.)
利用提示的--playlist参数,是将整个 playlist 下载的,但我只想下载第三个视频,这个该怎么办?
( github 的 wiki 里根本没有提到--playlist 参数还有什么骚操作)
Python中如何使用you-get从playlist中下载单独的视频?
https://github.com/iawia002/annie
这个软件能识别 p 参数。
import subprocess
import re
def download_single_video_from_playlist(playlist_url, video_index=1):
"""
从播放列表中下载单个视频
参数:
playlist_url: 播放列表URL
video_index: 要下载的视频序号(从1开始)
"""
try:
# 1. 先获取播放列表信息
cmd_info = ['you-get', '--json', playlist_url]
result = subprocess.run(cmd_info, capture_output=True, text=True, check=True)
# 2. 解析JSON输出获取视频列表
import json
playlist_data = json.loads(result.stdout)
# 3. 获取指定索引的视频URL
if 'playlist' in playlist_data:
videos = playlist_data['playlist']
if 1 <= video_index <= len(videos):
video_url = videos[video_index - 1]['url']
# 4. 下载单个视频
cmd_download = ['you-get', video_url]
subprocess.run(cmd_download, check=True)
print(f"✅ 已下载第 {video_index} 个视频")
else:
print(f"❌ 索引超出范围,播放列表共有 {len(videos)} 个视频")
else:
print("❌ 未找到播放列表信息")
except subprocess.CalledProcessError as e:
print(f"❌ 执行出错: {e}")
except json.JSONDecodeError:
print("❌ 解析播放列表信息失败")
except Exception as e:
print(f"❌ 发生错误: {e}")
# 使用示例
if __name__ == "__main__":
# 示例:下载播放列表中第3个视频
playlist_url = "https://www.youtube.com/playlist?list=YOUR_PLAYLIST_ID"
download_single_video_from_playlist(playlist_url, video_index=3)
核心原理:
- 先用
--json参数获取播放列表的完整信息 - 从JSON数据中提取指定索引的视频真实URL
- 用这个URL单独下载视频
更简单的命令行方法:
# 先获取播放列表信息
you-get --json "播放列表URL" > playlist.json
# 从json文件中找到想下载的视频URL
# 然后单独下载那个URL
you-get "单个视频URL"
实用技巧:
- 视频索引从1开始计数
- 某些网站可能需要添加
--playlist参数 - 可以用
-o指定输出目录
直接解析播放列表找特定视频链接就行。
我上次是改了下 bilibili.py 里面的代码就可以下了,不过好像没法合并(雾),手动 ffmpeg 合并的
猴,我去试试。谢谢了
刚才借用油猴的脚本,还行,就是步骤有点多。现在打算试试 推荐的 annie
带?p 的 但只匹配了 id/?p=page
改成 https://www.bilibili.com/video/av35557055/?p=3 试下
class BiliVideo(BiliBase):
name = u’哔哩哔哩 (Bilibili)’
def get_vid_title(self):
av_id = match1(self.url, ‘(?:/av|aid=)(\d+)’)
page_index = ‘1’
if “#page=” in self.url or “?p=” in self.url or ‘index_’ in self.url:
page_index = match1(self.url, ‘(?:#page|?p)=(\d+)’, ‘index_(\d+).’)
if page_index == ‘1’:
self.url = ‘https://www.bilibili.com/av{}/’.format(av_id)
else:
self.url = ‘https://www.bilibili.com/av{}/?p={}’.format(av_id, page_index)
经你这么提醒,去看了下代码,发现是 b 站的 url 格式变了
源代码:python<br> frag = urllib.parse.urlparse(self.url).fragment<br> # <a target="_blank" href="http://www.bilibili.com/video/av3141144/index_2.html#page=3" rel="nofollow noopener">http://www.bilibili.com/video/av3141144/index_2.html#page=3</a><br> if frag:<br> hit = re.search(r'page=(\d+)', frag)<br> if hit is not None:<br> page = hit.group(1)<br> aid = re.search(r'av(\d+)', self.url).group(1)<br> self.url = '<a target="_blank" href="http://www.bilibili.com/video/av" rel="nofollow noopener">http://www.bilibili.com/video/av</a>{}/index_{}.html'.format(aid, page)<br>
代码中解析的是/index_{}.html,而现在 b 站显示的是p={}
特意去试了下,旧的 url 格式还是可以用的
所以,要下载 playlist 中的单独的视频,只需把p={}换成/index_{}.html就 OK 了(不要忘记了.html )

