大神论坛

找回密码
快速注册
查看: 285 | 回复: 0

[源码] python爬虫工具源码之B站视频爬虫

主题

帖子

0

积分

初入江湖

UID
663
积分
0
精华
威望
0 点
违规
大神币
68 枚
注册时间
2023-10-14 10:48
发表于 2023-12-12 22:20
本帖最后由 ggxx223 于 2023-12-12 22:20 编辑

python爬虫工具源码之B站视频爬虫

更新了一下downloader函数

原来的加载有问题,今天看了一下重新写了一遍了,已经解决。

def downloader(self, data_url, title):
"""
数据下载
Parameters:
data_url: 数据地址
title: 标题
"""
if self.dir not in os.listdir(): # 创建文件夹
os.mkdir(self.dir)
with closing(requests.get(data_url, headers=self.video_headers, stream=True)) as response:
content_size = int(response.headers['content-length'])
content_mb = content_size / (1024 * 1024)
if response.status_code == 200:
sys.stdout.write(' [开始下载]\n')
sys.stdout.write(' [文件大小]: %0.2f MB\n' % content_mb)
video_name = os.path.join(self.dir, title)
# 保存视频,并输出进度
with tqdm(total=content_size, # 总大小
desc=' [下载进度]', # 进度条描述
leave=True, # 进度条不关闭
ascii=True, # 进度条不显示特殊字符
ncols=100, # 进度条长度
unit='iB', # 进度条单位
unit_scale=True, # 自动转换单位
unit_divisor=1024
) as pbar:
with open(video_name, 'wb') as file:
# 写入文件,下载速度与进度条加载速度不相关
for data in response.iter_content(chunk_size=1024): # 1024为每次读取的数据量
pbar.update(len(data)) # 更新进度条
file.write(data) # 写入文件
file.flush() # 刷新缓冲区
else:
print('~~~链接异常~~~' + '\r')
time.sleep(1)

二维码登录

这个是网上找到还可以就借鉴一下啦(=v=)
参考:https://blog.csdn.net/m0_66648798/article/details/128880243
这个讲的还算明白,目前可用。大家有兴趣可以自己去琢磨一下,原理不难。(我感觉是找登录数据与url难)
还有登录的cookie并不能保存很久,如果数据爬取的比较多,cookie会失效,这里就要重新扫描登录

import json
from typing import Dict, Any
import httpx
import qrcode
import os

def get_qrurl() -> dict[str, Any]:
"""返回qrcode链接以及token"""
with httpx.Client() as client:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE'
}
url = 'https://passport.bilibili.com/x/passport-login/web/qrcode/generate?source=main-fe-header'
data = client.get(url=url, headers=headers)
total_data = data.json()
qrcode_url = total_data['data']['url']
qrcode_key = total_data['data']['qrcode_key']
data = {}
data['url'] = qrcode_url
data['qrcode_key'] = qrcode_key
return data

def make_qrcode(data):
"""制作二维码"""
qr = qrcode.QRCode(
version=5,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(data['url'])
qr.make(fit=True)
# fill_color和back_color分别控制前景颜色和背景颜色,支持输入RGB色,注意颜色更改可能会导致二维码扫描识别失败
img = qr.make_image(fill_color="black")
img.show()

def sav_cookie(data, id):
"""用于储存cookie"""
try:
with open(f'./cookie/{id}.json', 'w') as f:
json.dump(data, f, ensure_ascii=False)
except FileNotFoundError:
os.mkdir('./cookie')
with open(f'./cookie/{id}.json', 'w') as f:
json.dump(data, f, ensure_ascii=False)

def main_run():
"""主函数"""
data = get_qrurl()
token = data['qrcode_key']
make_qrcode(data)
with httpx.Client() as client:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE'
}
url = f"https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key={token}&source=main-fe-header"
data_login = client.get(url=url, headers=headers) # 请求二维码状态
data_login = json.loads(data_login.text)
print(data_login)
code = int(data_login['data']['code'])
if code == 0:
cookie = dict(client.cookies)
print(cookie)
sav_cookie(cookie, 'test')
return load_cookie()

def load_cookie() -> dict:
"""用于加载cookie"""
try:
file = open(f'./cookie/test.json', 'r')
cookie = dict(json.load(file))
except FileNotFoundError:
msg = '未查询到用户文件,请确认资源完整'
cookie = 'null'
print(msg)
return cookie

if __name__ == "__main__":
main_run()

原代码要改的点:

import slogin
# 新建一个登录函数,方便之后加到终端
def output_cookie(self):
"""登录,保存cookie"""
print("登录扫描:")
cookie = slogin.main_run()
print("登录成功,您的cookie是:\n", cookie["SESSDATA"],"\n保存路径为:",os.path.join(os.getcwd(),"cookie"))

# 把我们保存的cookie加载到获得视频原数据url的函数就可以了
def get_download_url(self, arcurl):
.....
#
cookie = slogin.load_cookie() # 加载cookie
req1 = requests.get(url=url, headers=self.video_headers,cookies=cookie)

if __name__ == '__main__':
parser.add_argument('-login', '--login', required=False, help='登录')
if args.search and args.bvid:
print("批量下载和单独下载请分开使用")
if args.login:
B.output_cookie()

小小的聊一下

最后,这次更新就不投原创了,更新的比较少,登录代码也主要是别人的就投转载了。还有就是我太懒了,所以更新很慢。这次更新之后,我可以会去深入学习一下异步,坚持下来的话我会再更新的!(重新看了一遍自己写的代码感觉好乱啊>.<)


注:若转载请注明大神论坛来源(本贴地址)与作者信息。

返回顶部