b站学习视频python_python爬虫之b站视频下载(python学习笔记)

b站视频爬取(python学习笔记)

亲爱的b站自从在2020年3月23日将av号改为BV号后,之前的很多爬虫已经不能用了,暂时没看懂这操作的意义何在,反而一大串大小写英文字母加数字的BV号让人很难记,反爬嘛?(滑稽),那就爬一下玩一玩。

table='fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'

tr={}

for i in range(58):

tr[table[i]]=i

s=[11,10,3,8,4,6]

xor=177451812

add=8728348608

def dec(x):

r=0

for i in range(6):

r+=tr[x[s[i]]]*58**i

return (r-add)^xor

def enc(x):

x=(x^xor)+add

r=list('BV1 4 1 7 ')

for i in range(6):

r[s[i]]=table[x//58**i%58]

return ''.join(r)

作者:mcfx

链接:https://www.zhihu.com/question/381784377/answer/1099438784

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

av号和BV号的相互转化规则(牛牛牛),也可得出av号,这时候我们将BV号替换为av号:https://www.bilibili.com/video/av97325890

发现所打开的地址是一致的

接下来我们去找该视频对应的cid

F12打开开发者工具,点击network,刷新界面,耐心点找,得到以下数据,最后找到对应cid

得到aid和cid后我们要去寻找视频真正所在的url,B站的视频格式一般为flv

这时访问: https://api.bilibili.com/x/player/playurl?avid=97325890&cid=166148070&qn=32&type=&otype=json

继续F12打开可以看到

此时发现找到了视频真正的url

这里quality是视频质量

80: 高清 1080P

64: 高清 720P

32: 清晰 480P

16: 流畅 360P

下面只需要写代码将视频爬取下来即可

用到以下3个库

import requests

from lxml import html

import re

得到cid,可以从这个接口获得:https://api.bilibili.com/x/player/pagelist?aid=97325890&jsonp=jsonp

def get_cid(aid):

"""得到cid"""

header = {

'host': 'api.bilibili.com',

'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'

}

url = "https://api.bilibili.com/x/player/pagelist?aid={aid}&jsonp=jsonp".format(aid=aid)

response = requests.get(url,headers=header).json()

return response["data"][0]["cid"] ,response["data"][0]["part"]

接着获取视频的flv文件

def get_flvurl(url):

"""获得视频真实flv地址"""

header = {'host': 'api.bilibili.com',

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'}

response = requests.get(url,headers=header).json()

return response["data"]["durl"][0]["url"],response["data"]["durl"][0]["size"]

视频的存储

def save_movie(res,name):

"""保存视频"""

chunk_size = 1024

with open("{name}.flv".format(name = name),"wb") as f:

for data in res.iter_content(1024):

f.write(data)

结合python的tkinter库写了一个Gui界面,运行时发现按钮所绑定的方法处理起来需要点时间,然后导致界面会卡死,最后发现是单线程的原因,尝试引入多线程来解决问题,最后问题成功解决。

首先封装线程函数

def thread_it(func,*args):

"""将函数打包进线程内执行"""

# 创建

t = threading.Thread(target=func, args=args)

# 守护 !!!

t.setDaemon(True)

# 启动

t.start()

按钮绑定函数的写法

button1=Button(init_window,text="开始下载", bg="Cornsilk", width=8,height=1,command=lambda :thread_it(star))

完整代码如下(结合BV号转av号的规则)

from tkinter import *

from tkinter import messagebox

import tkinter.font as tkFont

import requests

from lxml import html

import re

import threading

table='fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'

tr={}

for i in range(58):

tr[table[i]]=i

s=[11,10,3,8,4,6]

xor=177451812

add=8728348608

def dec(x):

"""将BV号转化为av号"""

r=0

for i in range(6):

r+=tr[x[s[i]]]*58**i

return (r-add)^xor

def star():

url=text1.get(1.0,END)

url2 = "https://api.bilibili.com/x/player/playurl?avid={avid}&cid={cid}&qn=64&type=&otype=json"

headers2 = {

"host": "",

"Referer": "https://www.bilibili.com",

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"

}

BVid=re.findall("video/(.+)\?",url)

avid=dec(BVid[0])

text2.insert(1.0,'av号:'+str(avid)+'\n')

cid ,name = get_cid(avid)

text2.insert(3.0,'视频名称:'+name+'\n')

flv_url , size = get_flvurl(url2.format(avid=avid,cid=cid))

bulk = size / 1024 / 1024

text2.insert(5.0,"本视频大小为:%.2fM" % bulk+'\n')

h = re.findall("http://(.+)com",flv_url)

host = h[0]+"com"

headers2["host"] = host

res = requests.get(flv_url,headers=headers2,stream=True, verify=False)

if res.status_code==200:

text2.insert(7.0,'下载成功')

save_movie(res,name)

def get_cid(aid):

"""得到cid"""

header = {

'host': 'api.bilibili.com',

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'

}

url = "https://api.bilibili.com/x/player/pagelist?aid={aid}&jsonp=jsonp".format(aid=aid)

response = requests.get(url,headers=header).json()

return response["data"][0]["cid"] ,response["data"][0]["part"]

def get_flvurl(url):

"""获得视频真实flv地址"""

header = {'host': 'api.bilibili.com',

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'}

response = requests.get(url,headers=header).json()

return response["data"]["durl"][0]["url"],response["data"]["durl"][0]["size"]

def save_movie(res,name):

"""保存视频"""

chunk_size = 1024

with open("{name}.flv".format(name = name),"wb") as f:

for data in res.iter_content(1024):

f.write(data)

def thread_it(func,*args):

"""将函数打包进线程内执行"""

# 创建

t = threading.Thread(target=func, args=args)

# 守护 !!!

t.setDaemon(True)

# 启动

t.start()

#实例化一个父界面

init_window = Tk()

#界面参数

init_window.title('B站视频下载器') #窗口名称

init_window.geometry('600x500+400+150') #窗口大小

init_window["bg"] = "mistyrose" #窗口颜色

init_window.attributes("-alpha",0.9) #窗口透明度

init_window.iconbitmap("billbill.ico") #窗口图标

#标签

label1=Label(init_window,text="请输入视频链接",bg='mistyrose',font=('隶书',13))

label1.place(relx=0.38,rely=0.05)

label2=Label(init_window,text="消息",bg='mistyrose',font=('隶书',13))

label2.place(relx=0.46,rely=0.37)

#文本框

text1=Text(init_window,width=60, height=4)

text1.place(relx=0.15,rely=0.12)

text2=Text(init_window,width=60, height=15)

text2.place(relx=0.15,rely=0.42)

#按钮

button1=Button(init_window,text="开始下载", bg="Cornsilk", width=8,height=1,command=lambda :thread_it(star))

button1.place(relx=0.44,rely=0.25)

#窗口进入循环

init_window.mainloop()

运行结果

然后打开程序所在的目录下

B站的视频格式都是flv格式,可以用格式工厂(实测有用)转化为MP4文件

其实tkinter库写一写这些功能较为简单的小程序还是挺方便的。

原文链接:https://blog.csdn.net/weixin_43875683/article/details/107922300

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值