python实现b站自动下载收藏视频,防止视频和谐
ドラゴンボールのLong Lv4

点击收藏b站视频后,自动下载收藏视频


前言

详细代码已上传至GitHub,
访问链接:https://github.com/longhz/Collection_download_bilibili_video
当然,你也可以直接下载测试运行,我已经打包好了
下载链接:https://github.com/longhz/Collection_download_bilibili_video/releases

目的

1
2
3
写这个同步下载的小脚本是为了什么?
今年,我在b站寻找资料时候,发现我关注的up主一些视频下架了,收藏的视频失效了很多,
然后萌生了本地收藏视频的想法,想到了就开始动手去做

实现的结果

我最终要实现一个什么样的结果?

  • 我在b站点赞收藏的视频,分类规划文件夹
  • 根据不同的文件夹来生成不同的本地json
  • 脚本在执行后,每隔10分钟检测一次收藏夹是否有变动
  • 如果监测到有新收藏,会触发下载脚本
  • 下载的视频不能是音频和视频分开,得合二为一,所以会用的ffmpeg
  • 最终,在我本地电脑指定的保存视频路径中,能看到我的收藏视频

我已经实现了我的最终目标,我将脚本放在了我的nas后台,于是视频再也不会失效

下面是主体的运行逻辑和框架

生成本地json

获取收藏夹中的一页内容

当收藏夹的内容超过20,那么将会产生新的一页,这里pag来进行分页获取每一页的信息

1
2
3
4
5
6
7
8
9
10
11
12
# 获取收藏夹一页内容
def generate_fav_content_url(fid: int, page_number: int) -> str:
"""
获取收藏夹一页内容
https://api.bilibili.com/x/v3/fav/resource/list?
keyword=&order=mtime&type=0&tid=0&platform=web&jsonp=jsonp&ps=20&
media_id={fid}&pn={page_number}
:param fid: 收藏夹id
:param page_number: 收藏夹中页码
:return: 获取收藏夹一页内容url

return f'https://api.bilibili.com/x/v3/fav/resource/list?ps=20&media_id={fid}&pn={page_number}'

获取收藏夹信息

这里获取的信息用于解析出查询页面的前置条件

1
2
3
4
5
6
7
8
9
10
11
# 获取收藏夹信息
def generate_fav_url(fid: int) -> str:
"""
获取收藏夹信息
https://api.bilibili.com/x/v3/fav/resource/list?
pn=1&ps=20&keyword=&order=mtime&type=0&tid=0&platform=web&jsonp=jsonp&
media_id={fid}
:param fid: 收藏夹id
:return: 获取收藏夹信息url
"""
return f'https://api.bilibili.com/x/v3/fav/resource/list?ps=1&media_id={fid}'

查询页码

1
2
3
4
5
6
7
8
9
10
11
# 查询页码
def page_numbe(fid):
"""
fid: 视频收藏夹id
Returns: 分页统计
"""
resp = request_retry_json(generate_fav_url(fid))
media_count = resp['data']['info']['media_count']
page_count = math.ceil(media_count / 20)

return page_count

获取Response信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def request_retry(url: str, headers: dict = None, retry: int = 3) -> requests.Response:
if headers is None:
headers = {'Connection': 'close'}
headers['Connection'] = 'close'
while retry > 0:
try:
resp = requests.get(url, headers=headers)
return resp
except:
logging.error('request %s error: %s' % (url, sys.exc_info()[0]))
time.sleep(5 - retry)
retry -= 1
raise requests.RequestException

def request_retry_json(url: str, headers=None, retry: int = 3) -> dict:
return json.loads(request_retry(url, headers, retry).text)

读取网页信息,并转化为son格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
def request_info(resp):

bili_json1 = []
for a in resp['data']['medias']:
# 视频搜索id
av_id = a['id']
# 视频搜索av_id链接
av_id_link = a['link']
# 播放时长
n = int(a['duration'])
m = int(n / 60)
s = n - m * 60
# print(f"可以换算成 {m}分钟 {s}秒。")
duration = f"时长:{m}分钟{s}秒"

# 类型
type = a['type']
# 标题
title = a['title']

# 去除格式和特殊符号
re_exp = u"([^\u4e00-\u9fa5\u0030-\u0039\u0041-\u005a\u0061-\u007a\’!\"#$%&\'()*+,-./:;<=>?@,。?、…【】《》?“”‘’!["u"\\]^_`{|}~\s])"
video_title = str(title).strip(re_exp)

# 对一些格式的保留和替换
video_name = "".join(video_title.split())
video_name = (((video_name.replace("/", "-")).replace("】", "-")).replace("[", "-")).replace("【", "-")
video_name = (((video_name.replace(";", "-")).replace("\n", "")).replace("]", "-")).replace("r&b", "")
video_name = (((video_name.replace("(", "-")).replace(")", "")).replace(" ", "")).replace("&", "与")
video_name = (((video_name.replace("--", "-")).replace("(", "")).replace(")", "")).replace("&","")
video_name = (((video_name.replace("amp;", "")).replace("|", "-")).replace("《", "")).replace("》", "")

# 图片链接
cover = a['cover']
# 摘要
intro = a['intro']
# 页数
page = a['page']
# up主个人id
up_mid = a['upper']['mid']
# up主昵称
up_name = a['upper']['name']
# up主头像
up_face = a['upper']['face']
# 视频id
bv_id = a['bv_id']
# 视频链接
bv_link = "https://www.bilibili.com/video/" + a['bv_id']
# 该视频收藏人数
bv_collect = a['cnt_info']['collect']
# 该视频播放次数
bv_play = a['cnt_info']['play']
# 当前观看人数
bv_danmaku = a['cnt_info']['danmaku']

bili_json = {
'title': video_name,
'intro': intro,
'cover': cover,
'bv_id': bv_id,
'bv_link': bv_link,
'page': page,
'av_id': av_id,
'av_id_link': av_id_link,
'type': type,
'duration': duration,
'bv_collect': bv_collect,
'bv_play': bv_play,
'bv_danmaku': bv_danmaku,
'up_mid': up_mid,
'up_name': up_name,
'up_face': up_face,
'is_Download': 0
}
bili_json1.append(bili_json)

return bili_json1

json调用格式清理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def write_json(resp, json_file_path_name):

bili_create_json(json_file_path_name)
try:
bili_json_format_eliminate(json_file_path_name)
except Exception as err:
pass
with open(json_file_path_name, 'a', encoding='utf-8') as fw:
fw.write(',')
json.dump(resp, fw, indent=4, ensure_ascii=False)
fw.write('\n')
# print("写入完毕")
fw.close()
bili_create_json(json_file_path_name)
bili_tihuan(json_file_path_name)

写入json文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def read_write_json(resp, json_file_path_name):
"""
文件操作中的 r, r+, a, a+, w, w+ 几种方式的区别:
r只读,r+ 可读可写,若文件不存在,报错;
w只写,w+ 可读可写,二者都会将文件内容清零,若文件不存在,创建;
a附加写方式打开,不可读,a+ 附加读写方式打开,二者都是若文件不存在,创建;
"""
my_file = Path(json_file_path_name)
resp1 = request_info(resp)
a = 0
b = 0

if my_file.is_file():
for rss in resp1:
tt1 = rss['bv_id']
title_ysx = str(rss['title'].strip())
flag = select_json(tt1, json_file_path_name)

if flag == 1:
# print("检测到已存在json文件中")
a = a + 1
# pass
else:
if title_ysx in "已失效视频":
print("该视频已被up主删除,已失效,为您跳过该条新增记录!")
# b = b + 1
else:
write_json(rss, json_file_path_name)
b = b + 1
print(f'新增了第{b}条收藏记录,标题:' + rss['title'])
print(f'已检测到已存在收藏记录{a}条,新增了{b}条收藏记录')
else:
print("检测到文件不存在,已为您新建json文件")
for rss in resp1:
title_ysx = str(rss['title'].strip())
if title_ysx in "已失效视频":
print("该视频已被up主删除,已失效,为您跳过该条新增记录!")
else:
write_json(rss, json_file_path_name)
b = b + 1
print(f'新增了第{b}条收藏记录,标题:' + rss['title'])
print(f'已检测到已存在收藏记录{a}条,新增了{b}条收藏记录')

创建并添加json文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def ins_json(fid: int, json_name: str, file_dir):
# fid: 收藏夹id
fid = fid
# page_number: 收藏夹中页码
page_number = page_numbe(fid)
# 文件名称
json_name = json_name + '.json'

Subscribe = os.path.join(file_dir, 'Subscribe_json')
mkdir_folder(Subscribe)
# json文件路径名称
json_file_path_name = File_dir(Subscribe, json_name)
# total 负责做累加和
total = 1

while total <= page_number:
url = generate_fav_content_url(fid, total)
resp = request_retry_json(url)
read_write_json(resp, json_file_path_name)
print(f'第{total}页收藏夹已记录~~\n')
total += 1

print("执行完毕")

下载收藏夹中的视频

请求的url地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 请求的url地址
def get_response(html_url):
"""
Args: 发送请求,以及获取数据函数
html_url: 请求的url地址
Returns: 返回请求服务器返回的响应数据
"""
# 请求代码,在发送请求前,需要进行伪装 headers 请求头
# user-agent 浏览器基本标识 用户代理 基本伪装 反爬手段
# <Response [200]> 对象response响应对象 200 状态码 表示请求成功
# 404 网址可能出错
# 403 网址没有权限,出现 403 加防盗链 referer ,是为了告诉服务器,我们发送请求的url地址,是从哪里跳转过来的

headers = {
"referer": "https://search.www.bilibili.com",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
}

response = requests.get(url=html_url, headers=headers, stream=True) # 请求代码
# stream 字节流 (可选,开启后可用于判断大小以及做进度条使用)
# 一般选取小而快的内容时,将stream设置为false或者不加也许,可以快速的读取response.content内容
# 当stream开启后,后面需要自己执行response.close()操作进行关闭接收,否则只有所有的响应体数据被读取完毕连接才会被释放,如果用with可以不用close()

return response

视频的详情页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def get_video_info(html_url):
"""
获取视频标题 /音频 url地址 / 视频画面url地址
Args:
html_url: 视频的详情页

Returns: 视频标题 /音频 url地址 / 视频画面url地址

"""

response = get_response(html_url=html_url)
# response.text 获取响应体的文本数据
# print(response.text)
# 解析数据 提取视频标题 re正则表达式 css选择器 xpath bs4 parsel lxml (解析模块) jsonpath 主要提取json数据

# 正则表达式提取的数据内容 返回都是列表数据类型[0] 列表 所返回的索引取值( 0或者-1都行,0是从左往右,-1是从右往左)
title = re.findall('<h1 title="(.*?)" class="video-title tit">', response.text)[0] # 标题

# 去除格式和特殊符号
re_exp = u"([^\u4e00-\u9fa5\u0030-\u0039\u0041-\u005a\u0061-\u007a\’!\"#$%&\'()*+,-./:;<=>?@,。?、…【】《》?“”‘’!["u"\\]^_`{|}~\s])"
video_title = str(title).strip(re_exp)
# 替换和保留一些格式
video_name = "".join(video_title.split())
video_name = (((video_name.replace("/", "-")).replace("】", "-")).replace("[", "-")).replace("【", "-")
video_name = (((video_name.replace(";", "-")).replace("\n", "")).replace("]", "-")).replace("r&b", "")
video_name = (((video_name.replace("(", "-")).replace(")", "")).replace(" ", "")).replace("&", "与")
video_name = (((video_name.replace("--", "-")).replace("(", "")).replace(")", "")).replace("&", "")
video_name = (((video_name.replace("amp;", "")).replace("|", "-")).replace("《", "")).replace("》", "")


html_data = re.findall('<script>window.__playinfo__=(.*?)</script>',response.text)[0]
# html_data 是<class 'str'>数据类型
# 为了更加方便提取数据,可以字符串数据 转换成 字典数据类型
json_data = json.loads(html_data)
# 根据键值对取值
audio_url = json_data['data']['dash']['audio'][0]['base_url']
video_url = json_data['data']['dash']['video'][0]['base_url']
video_info = [video_name, audio_url, video_url]

return video_info

下载保存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
def save(title, audio_url, video_url, tmp_dir):
"""

Args: 保存数据函数
title: 视频标题
audio_url: 音频url
video_url: 视频画面url
Returns:

"""

au_response = get_response(html_url=audio_url)
audio_content = au_response.iter_content(chunk_size=1024)
au_total = int(au_response.headers.get('content-length', 0))

vi_response = get_response(html_url=video_url)
video_content = vi_response.iter_content(chunk_size=1024)
vi_total = int(vi_response.headers.get('content-length', 0))

with open(tmp_dir + '/' + title + '.mp3', mode='wb') as f, tqdm(
desc="音频下载进度",
total=au_total,
unit='iB',
unit_scale=True,
unit_divisor=1024
) as bar:
for data in audio_content:
size = f.write(data)
bar.update(size)
f.close()

with open(tmp_dir + '/' + title + '.mp4', mode='wb') as f, tqdm(
desc="视频下载进度",
total=vi_total,
unit='iB',
unit_scale=True,
unit_divisor=1024
) as bar:
for data in video_content:
size = f.write(data)
bar.update(size)
f.close()

print(title, "已下载保存至临时目录:" + tmp_dir + '/' + title)

下载主函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def Download_main(bv_id, tmp_dir, Download_videos):
"""

Args: 下载主函数
bv_id: bv号
tmp_dir:临时目录
Download_videos:实际保存目录
Returns:

"""
url = f'https://www.bilibili.com/video/{bv_id}'
video_info = get_video_info(url) # [title, audio_url, video_url]

save(video_info[0], video_info[1], video_info[2], tmp_dir)
merge_data(video_info[0], tmp_dir, Download_videos)

数据合并 - 视频合并(使用了ffmpeg)

1
2
3
4
5
6
7
def merge_data(video_name, tmp_dir, Download_videos):
""" 数据合并 - 视频合并 """

print('视频合并开始:', video_name)
cmd = f"ffmpeg -i {tmp_dir}/{video_name}.mp4 -i {tmp_dir}/{video_name}.mp3 -c:v copy -c:a aac -strict experimental {Download_videos}/{video_name}.mp4"
subprocess.run(cmd, shell=True)
print(f'视频合成结束,已将视频保存至路径: {Download_videos}/{video_name}.mp4')

读取json文件,执行脚本,修改下载状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def bili_json(folder_dir, Download_videos, json_file_path_name):
"""

Args: 读取json文件,执行脚本,修改下载状态
folder_dir:
Download_videos:

Returns:

"""
# 休眠10s
sleepTime = 10

json_flag = json_file_path_name.strip()
# 判断路径是否存在 存在 True 不存在 False
isExists = os.path.exists(json_flag)

# 判断结果
if not isExists:
print(json_file_path_name + "不存在,已为您跳过!")
else:
with open(json_file_path_name, 'r', encoding='utf-8') as jsonFile:

data = json.load(jsonFile)
for aa in data:
bv_id = aa['bv_id']
is_Download = aa['is_Download']
title = aa['title']

# print(type(is_Download))
if is_Download == 0:

bb = str(aa['is_Download']).replace('0', '1')
print(f"\n检测到新收藏,标题为:{title},正在下载,请稍后")
bili_download_main(folder_dir, Download_videos, bv_id)
aa['is_Download'] = int(bb)
# print("下载脚本执行完毕!,休眠30s后,继续执行! \n ------------------------------------------------")
with open(json_file_path_name, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)
f.close()
# jsonFile.close()
print(f"休眠10s后,将执行下载命令! \n ------------------------------------------------")
time.sleep(sleepTime)

else:
jsonFile.close()
print(title + "\n检测到已存在下载历史,已为你跳过下载~ \n ------------------------------------------------")

下载前校验文件夹是否存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def bili_download_main(folder_dir, Download_videos, bv_id):
# url = 'https://www.bilibili.com/video/BV1xL411M7yg/'
# video_info = get_video_info(url)
# print(video_info)

# 键盘输入
# keyword = input("输入要下载的bv号:")
# main(keyword)
start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
start_time = datetime.strptime(start_time, r"%Y-%m-%d %H:%M:%S")

try:
mkdir_folder(folder_dir)
print("临时文件夹——创建成功")

mkdir_folder(Download_videos)
print("视频实际存储文件夹——创建成功")

Download_main(bv_id, folder_dir, Download_videos)
print("视频下载成功")

end_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
end_time = datetime.strptime(end_time, r"%Y-%m-%d %H:%M:%S")
diff = end_time - start_time

rm_folder(folder_dir)
print("临时文件夹——已删除")
print(f"总计运行{diff.total_seconds()}秒")
except Exception as err:
end_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
end_time = datetime.strptime(end_time, r"%Y-%m-%d %H:%M:%S")
diff = end_time - start_time
print("临时文件夹——已删除")
print(f"总计运行{diff.total_seconds()}秒")

config.ini设置与导入包

1
2
3
4
5
def config_collection():
# 导入configparser模块,
conf = ConfigParser()

return conf

config.ini设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[bili_collection]
fid_1: 1781782216
fid_1_name: 测试收藏
;如果有多个收藏夹,复制fid_序列数字,如下面所示
;fid_2: #
;fid_2_name: #
[video_dir]
;临时文件夹名称
Temporary_folder: tmp
;视频文件夹名称
Download_videos_folder: Download_videos
;具体保存路径
windows_dir: D:/Downloads/video/
;如果linux使用
;linux_dir: /tmp/

创建文件夹和替换文本

创建文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def mkdir_folder(path):
"""
Args:
path: 创建临时文件
Returns:
"""
# 去除首位空格
path = path.strip()
# 去除尾部 \ 符号
path = path.rstrip("\\")
# 判断路径是否存在 存在 True 不存在 False
isExists = os.path.exists(path)

# 判断结果
if not isExists:
# 如果不存在则创建目录
# 创建目录操作函数
os.makedirs(path)
# print(path+' 创建成功')
return True
else:
# 如果目录存在则不创建,并提示目录已存在
# print(path+' 目录已存在')
return False

删除文件和文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def rm_folder(dir):
"""

Args:
dir: 遍历删除文件夹和文件

Returns:

"""
# 引入模块
import os
# 判断是否是文件夹,如果是,递归调用rmdir()函数
if (os.path.isdir(dir)):
# 遍历地址下的所有文件
for file in os.listdir(dir):
# 删除文件
oo = dir + r'/' + file
os.remove(oo)
# print("文件已删除")
# 继续删除文件夹
rm_folder(dir)
# 如果是空文件夹,直接删除
if (os.path.exists(dir)):
os.rmdir(dir)
# print(dir, "文件夹删除成功")
# 如果是文件,直接删除
else:
if (os.path.exists(dir)):
os.remove(dir)
print(dir, "文件删除成功")

json文件格式初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def bili_create_json(json_file_path_name):
ffe = os.path.exists(json_file_path_name)

if ffe == True:

with open(json_file_path_name, 'a', encoding='utf-8') as fw:
fw.write(']\n')
# print("写入完毕")
fw.close()
else:
with open(json_file_path_name, 'w+', encoding='utf-8') as fw:
fw.write('[')
# print("创建写入完毕")
fw.close()

文本格式清理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def bili_json_format_eliminate(json_file_path_name):
matchPattern = re.compile(r']')

file = open(json_file_path_name, 'r', encoding='UTF-8')
lineList = []
while 1:
line = file.readline()
if not line:
# print("指定格式已清理")
break
elif matchPattern.search(line):
pass
else:
lineList.append(line)
file.close()
file = open(json_file_path_name, 'w', encoding='UTF-8')
for i in lineList:
file.write(i)
file.close()

文本查询和替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def bili_tihuan(json_file_path_name):
# 创建一个变量并存储我们要搜索的文本
search_text = "[,"

# 创建一个变量并存储我们要添加的文本
replace_text = "["

# 使用 open() 函数以只读模式打开我们的文本文件
with open(json_file_path_name, 'r', encoding='UTF-8') as file:
# 使用 read() 函数读取文件内容并将它们存储在一个新变量中
data = file.read()

# 使用 replace() 函数搜索和替换文本
data = data.replace(search_text, replace_text)

# 以只写模式打开我们的文本文件以写入替换的内容
with open(json_file_path_name, 'w', encoding='UTF-8') as file:
# 在我们的文本文件中写入替换的数据
file.write(data)

# 打印文本已替换
# print("文本已替换")

查询验证文本是否存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def select_json(bv_id, json_file_path_name):
with open(json_file_path_name, 'r', encoding='utf-8') as jsonFile:
data = json.load(jsonFile)
aa = 0
for data_a in data:
if bv_id == data_a['bv_id']:
# print("存在")
aa = aa+1
jsonFile.close()
return aa
else:
pass
# print(aa)
jsonFile.close()
return aa

判断系统平台和文件保存路径

判断当前运行平台是windows还是linux

1
2
3
4
5
6
7
8
9
10
def isWondowsorLinux():
''' 判断当前运行平台 :return: '''
sysstr = platform.system()
if (sysstr == "Windows"):
return True
elif (sysstr == "Linux"):
return False
else:
print("Other System ")
return False

根据系统环境分配文件保存路径

1
2
3
4
5
6
7
8
9
10
def File_dir(file_dir: str, json_name: str):
mkdir_folder(file_dir)

# 判断当前系统环境
if isWondowsorLinux() == True:
windows_dir = os.path.join(file_dir, json_name)
return windows_dir
else:
linux_dir = os.path.join(file_dir, json_name)
return linux_dir

调用收藏同步和执行下载

日期获取

1
2
3
def getDate():
date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return "当前时间:"+date

config 初始化

1
2
3
4
5
6
7
conf = config_collection()
# 获取当前目录路径
file_dir = os.path.dirname(os.path.abspath(__file__))
# 实际文件路径
CONF_FILE = os.path.join(file_dir, 'config.ini')
# 实例化语言格式
conf.read(CONF_FILE, encoding="utf-8")

同步收藏夹

1
2
3
4
5
6
7
8
9
10
def tb_sc():
# 获取配置文件的参数信息
fid_1 = conf.get("bili_collection", "fid_1")
fid_1_name = conf.get("bili_collection", "fid_1_name")
ins_json(fid_1, fid_1_name, file_dir)

# ---如果有多个收藏夹,可以仿照下面复制,要记得修改数字---
# fid_2 = conf.get("bili_collection", "fid_2")
# fid_2_name = conf.get("bili_collection", "fid_2_name")
# ins_json(fid_2, fid_2_name, file_dir)

下载收藏夹视频

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def download_video():
# 获取配置文件的参数信息
tmp_file_name = conf.get("video_dir", "Temporary_folder")
download_file_name = conf.get("video_dir", "Download_videos_folder")
# 根据系统来使用linux还是windows
# linux_dir = conf.get("video_dir", "linux_dir")
windows_dir = conf.get("video_dir", "windows_dir")

# 临时文件夹路径
folder_dir_path = File_dir(windows_dir, tmp_file_name)
# 视频下载实际保存路径
Download_videos_path = File_dir(windows_dir, download_file_name)
# 收藏夹视频json文件路径
json_file_path_name1 = File_dir((os.path.join(file_dir, 'Subscribe_json')), (conf.get("bili_collection", "fid_1_name")) + ".json")
# 调用下载
bili_json(folder_dir_path, Download_videos_path, json_file_path_name1)

# ---如果有多个收藏夹,可以仿照下面复制,要记得修改数字---
# json_file_path_name2 = File_dir((os.path.join(file_dir, 'Subscribe_json')), (conf.get("bili_collection", "fid_2_name")) + ".json")
# bili_json(folder_dir_path, Download_videos_path, json_file_path_name2)

运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 1分=60s,休眠10分钟
sleepTime = 600
# 添加err_log日志文件
logging.basicConfig(filename='err.log')

while True:
try:
# 执行收藏同步
tb_sc()
print(getDate() + " 收藏记录执行完毕!")

try:
# 执行视频下载
download_video()
print(getDate() + " 视频下载执行完毕!")
except Exception as e:
s = traceback.format_exc()
print(getDate() + " 视频下载执行失败!")
logging.error(s)

except Exception as e:
s = traceback.format_exc()
print(getDate() + " 收藏记录执行失败!")
logging.error(s)

print("脚本执行完毕!" + getDate() + " ,休眠10分钟后,继续执行!")
# 休眠10分钟
time.sleep(sleepTime)
continue
  • 本文标题:python实现b站自动下载收藏视频,防止视频和谐
  • 本文作者:ドラゴンボールのLong
  • 创建时间:2022-10-01 18:17:21
  • 本文链接:https://zhongshenglong.xyz/2022/10/01/python-bilibili-Collection-Download/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论