python 下载bilibili视频

python 下载bilibili视频,第1张

python 下载bilibili视频

说明:

1.清晰度的选择要登录,暂时还没做,目前下载的视频清晰度都是默认的480P

2.进度条仿linux的,参考了一些博客修改了下,侵删

3.其他评论,d幕之类的相关爬虫代码放在了https://github.com/teleJa/bilibili

4.判断sys.argv那个地方是因为一些爬虫调用了该文件,如果感觉不方面,直接传递视频番号进去就可以了

下载过程如图

直接上代码:

 import requests
import re
import os
import json
import sys
import math
from lxml import etree class BLDSplider:
regex_cid = re.compile("\"cid\":(.{8})") def __init__(self, aid):
self.aid = aid self.origin_url = "https://www.bilibili.com/video/av{}?from=search&seid=9346373599622336536".format(aid)
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
} self.url = "https://api.bilibili.com/x/player/playurl?avid={}&cid={}&qn=0&type=&otype=json" def check_dir(self, author_name):
# 检查目录
self.parent_path = "e:/bilibili/" + author_name + "/" + str(self.aid) + "/"
if not os.path.exists(self.parent_path):
os.makedirs(self.parent_path) self.video_name = self.parent_path + str(self.aid) + ".mp4" def parse_url(self, item):
cid = item["cid"]
print("aid:%s cid:%s" % (str(self.aid), cid))
title = item["title"]
print("title:%s" % title) self.headers["Referer"] = self.origin_url
# 视频
response = requests.get(self.url.format(self.aid, cid), headers=self.headers)
if response.status_code == 200:
result = json.loads(response.content.decode())
durl = result["data"]["durl"][0]
video_url = durl["url"]
print("video_url:%s" % video_url)
# 视频大小
size = durl["size"]
print("size:%s,约%2.2fMB" % (size, size / (1024 * 1024)))
video_response = requests.get(video_url, headers=self.headers, stream=True)
if video_response.status_code == 200:
with open(self.video_name, "wb") as file:
buffer = 1024
count = 0
while True:
if count + buffer <= size:
file.write(video_response.raw.read(buffer))
count += buffer
else:
file.write(video_response.raw.read(size % buffer))
count += size % buffer
file_size = os.path.getsize(self.video_name)
# print("\r下载进度 %.2f %%" % (count * 100 / size), end="") width = 50
percent = (count / size)
use_num = int(percent * width)
space_num = int(width - use_num)
percent = percent * 100
print('\r进度:[%s%s] %d%%' % (use_num * '#', space_num * ' ', percent), file=sys.stdout,
flush=True, end="")
if size == count:
break
print("\r\n") # 获取视频相关参数
def get_video_info(self):
response = requests.get(self.origin_url, headers=self.headers)
item = dict()
if response.status_code == 200:
# author
html_element = etree.HTML(response.content.decode())
author = dict()
author_name = html_element.xpath(
"/html/body/div[@id='app']/div[@class='v-wrap']/div[@class='r-con']/div[@id='v_upinfo']//a[@report-id='name']/text()")[
0]
# 通常是微博,微信公众号等联系方式
author_others = html_element.xpath(
"/html/body/div[@id='app']/div[@class='v-wrap']/div[@class='r-con']/div[@id='v_upinfo']//div[@class='desc']/@title")[
0]
author["name"] = author_name
author["others"] = author_others
item["author"] = author # cid
cid = BLDSplider.regex_cid.findall(response.content.decode())[0]
item["cid"] = cid
info_url = "https://api.bilibili.com/x/web-interface/view?aid={}&cid={}".format(self.aid, cid)
info_response = requests.get(info_url, headers=self.headers)
if info_response.status_code == 200:
data = json.loads(info_response.content.decode())["data"]
# 视频简介
desc = data["desc"]
item["desc"] = desc # title
title = data["title"]
item["title"] = title stat = data["stat"]
# 播放量
view = stat["view"]
item["view"] = view # d幕
danmaku = stat["danmaku"]
item["danmaku"] = danmaku # 评论
reply = stat["reply"]
item["reply"] = reply # 硬币
coin = stat["coin"]
item["coin"] = coin # 点赞
like = stat["like"]
item["like"] = like # 收藏
favorite = stat["favorite"]
item["favorite"] = favorite # 分享
share = stat["share"]
item["share"] = share
self.check_dir(item["author"]["name"])
# 视频参数
with open(self.parent_path + "video_info.txt", "w") as file:
file.write(json.dumps(item, ensure_ascii=False, indent=2))
return item def run(self):
item = self.get_video_info()
self.parse_url(item) def main():
#
aid = 55036734
if len(sys.argv) >= 2:
if sys.argv[1]:
aid = sys.argv[1]
splider = BLDSplider(aid)
splider.run() if __name__ == '__main__':
main()

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/589526.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-12
下一篇 2022-04-12

发表评论

登录后才能评论

评论列表(0条)

保存