简单的python爬虫工具,B站视频爬虫
分享一个我自己写的pythonB站视频爬虫,写的比较粗糙
当然网上一堆B站视频获取的工具,也不差我这个粗糙的python脚本,就是分享出来大家一起讨论学习,如果大家有什么好的想法和功能我们可以一起聊聊。
这里分享一个我自己用的B站视频下载的工具BBDown,很好用,作者也是在一直更新。
必要工具ffmpeg,建议还是放在你的python项目目录下(我不知道为什么配置的环境变量没有生效)
这个如果想爬取高清视频就把自己的cookie加到api_headers。这里进度条加载有点问题,就是视频太小了进度条可能加载不完全,还有就是视频合成也有点问题,有时视频合成不了
代码如下:
import argparseimport requests, re, sys, os, time
from contextlib import closing
from urllib import parse
from lxml import etree
import subprocess
from tqdm import tqdmclass BiliBili:def __init__(self, dirname):self.search_headers = {'authority': 'search.bilibili.com','Accept': '*/*','Referer': 'https://www.bilibili.com/','Accept-Encoding': 'gzip, deflate, br','Accept-Language': 'zh-CN,zh;q=0.9','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.61',}self.video_headers = {'authority': 'www.bilibili.com','Referer': 'https://www.bilibili.com/','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/118.0.0.0 Safari/537.36'}self.api_headers = {'authority': 'api.bilibili.com','Accept': '*/*','Referer': 'https://www.bilibili.com/','Accept-Encoding': 'gzip, deflate, br','Accept-Language': 'zh-CN,zh;q=0.9',# 'cookie':"",'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/119.0.0.0 Safari/537.36'}self.sess = requests.Session()self.dir = dirnamedef downloader(self, data_url, title):"""数据下载Parameters:data_url: 数据地址title: 标题"""if self.dir not in os.listdir():os.mkdir(self.dir)size = 0with closing(self.sess.get(data_url, headers=self.video_headers, stream=True)) as response:chunk_size = 1000content_size = int(response.headers['content-length'])content_mb = content_size / 1000 / 1000if 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=False, ncols=100, unit='B',unit_scale=True) as pbar:with open(video_name, 'wb') as file:if content_mb < 3:file.write(response.content)for i in range(5):pbar.update(content_size/5)else:for data in response.iter_content(chunk_size=chunk_size):file.write(data)pbar.update(len(data))size += len(data)file.flush()sys.stdout.write('\n')sys.stdout.write(' [下载完成]' + '\r')sys.stdout.flush()if size / content_size == 1:print('\n')else:print('~~~链接异常~~~'+'\r')time.sleep(1)def search_video(self, keyword, page=1):"""搜索页视频信息Parameters:keyword: 关键词page: 页码Returns:videos[titles,bvs]titles:标题bvs: bv号"""url = f'https://search.bilibili.com/all?keyword={parse.quote(keyword)}&page={page}&o=30'req = self.sess.get(url=url, headers=self.search_headers)html = etree.fromstring(req.text, etree.HTMLParser())bvs = html.xpath('//div[@class="bili-video-card__info--right"]/a/@href')[:3]titles = html.xpath('//div[@class="bili-video-card__info--right"]/a/h3/@title')[:3]videos = []for i, j in zip(titles, bvs):for c in u'´★☆❤◦\/:*?"<>|':i = i.replace(c, '')tmp = [i, j]videos.append(tmp)# 输出搜索页面视频标题和视频urlprint(videos)return videos# titles, bvsdef get_download_url(self, arcurl):"""获取详情页数据信息Parameters:arcurl: 视频播放地址Returns:accept_description: 视频清晰度video_data: 视频地址audio_data: 音频地址title: 标题"""xp = 'BV\d.{9}'if re.findall(xp, arcurl):bv = re.findall(xp, arcurl)[0]url = f'https://api.bilibili.com/x/web-interface/view?bvid={bv}' # avid&cidelse:print('视频BV号解析失败,请检查输入的bv号是否正确')exit(0)req1 = self.sess.get(url=url, headers=self.video_headers)ac_json = req1.json()avid = ac_json['data']['aid']cid = ac_json['data']['cid']url2 = f'https://api.bilibili.com/x/player/wbi/playurl?avid={avid}&cid={cid}&fnval=4048' # playurltitle = ac_json['data']['title']req2 = self.sess.get(url=url2, headers=self.api_headers)playinfo_dict = req2.json()accept_description = playinfo_dict["data"]["accept_description"] # 视频清晰度# id = [playinfo_dict["data"]["dash"]["video"][0]["id"]]audio_data = [playinfo_dict["data"]["dash"]["audio"][0]["baseUrl"]] # 音频数据video_data = [playinfo_dict["data"]["dash"]["video"][0]["baseUrl"]]# print(id)if not audio_data and not video_data:print('视频解析失败')exit(0)return [accept_description, video_data, audio_data,title]def merge_data(self, dir, video_name):"""视频合成Parameters:dir: 目录video_name: 视频名"""time.sleep(0.1)if video_name+'_2' in os.listdir(self.dir):print( '合成视频已存在')exit(0)else:print('视频合成开始:', video_name)cmd = f"cd {dir} & ffmpeg -y -i {video_name}.mp4 -i {video_name}.mp3 -c:v copy -c:a aac -strict experimental -map 0:0 -map 1:0 {video_name}_2.mp4 && del {video_name}.mp4 {video_name}.mp3"subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)print('视频合成结束:', video_name+'\r')def search_downloader(self, keyword,page=1):"""批量爬取搜索页视频Parameters:keyword: 关键词page: 页码"""if self.dir not in os.listdir():os.mkdir(self.dir)for j in range(page):s_video = self.search_video(keyword, j+1)for i in range(len(s_video)):title = s_video[i][0]arcurl = s_video[i][1]if title not in os.listdir(self.dir):videos_data = self.get_download_url(arcurl)[1]audio_data = self.get_download_url(arcurl)[2]if not videos_data[0] or not audio_data[0]:print('第[ %d ]页:%s视频或音频解析失败,跳过下载:' % (1 + j, title))continue # Skip video download if video or audio parsing failsfname = title + '.mp4'print('第[ %d ]页:视频[ %s ]下载中:' % (1 + j, fname)) # 打印页码和指定下载视频self.downloader(videos_data[0], fname)print('视频下载完成!')fname = title + '.mp3'print('第[ %d ]页:音频[ %s ]下载中:' % (1 + j, fname)) # 打印页码和指定下载视频self.downloader(audio_data[0], fname)print('音频下载完成!')# 创建临时文本文件用于合并视频音频try:video_name = titledirz = self.dirself.merge_data(dirz, video_name)except:print('请安装FFmpeg,并配置环境变量 http://ffmpeg.org/')def a_video_download(self,bv):"""单个视频爬取Parameters:bv: 关bv号"""video_info = self.get_download_url(bv)title = video_info[3]fname = "{0}.mp4".format(title)print('视频[ %s ]下载中:' % fname) # 打印页码和指定下载视频self.downloader(video_info[1][0], fname)print('视频下载完成!')fname = '{0}.mp3'.format(title)print('音频[ %s ]下载中:' % fname) # 打印页码和指定下载视频self.downloader(video_info[2][0], fname)print('音频下载完成!')self.merge_data(self.dir,video_info[3])if __name__ == '__main__':if len(sys.argv) == 1:sys.argv.append('--help')parser = argparse.ArgumentParser()parser.add_argument('-d', '--dir', required=True, help='必要,下载路径')parser.add_argument('-bv', '--bvid', required=False, help='下载指定bv视频')parser.add_argument('-s', '--search', required=False, action='store_true', help='批量下载搜索页视频')parser.add_argument('-k', '--keyword', required=False, help='搜索关键词内容')parser.add_argument('-p', '--pages', required=False, help='需要下载页码数', type=int)args = parser.parse_args()B = BiliBili(args.dir)if args.search:if args.keyword and args.pages is None:print('请输入搜索关键词和页码')exit(0)B.search_downloader(args.keyword, args.pages)if args.bvid:if args.search or args.keyword or args.pages:print('下载单个视频请只输入BV号')exit(0)B.a_video_download(args.bvid)# return [accept_description, video_data, audio_data, title]# B = BiliBili('猫')# url = 'https://www.bilibili.com/video/BV1Jy4y1K7yp/'# a=B.get_download_url(url)# B.downloader(a[1][0], a[3])
相关文章:
简单的python爬虫工具,B站视频爬虫
分享一个我自己写的pythonB站视频爬虫,写的比较粗糙 当然网上一堆B站视频获取的工具,也不差我这个粗糙的python脚本,就是分享出来大家一起讨论学习,如果大家有什么好的想法和功能我们可以一起聊聊。 这里分享一个我自己用的B站视…...
Shopee买家号有什么作用?如何才能拥有大量的虾皮买家号?
对于卖家而言,用shopee买家号进行测评有以下几点好处: 1、随时随地可以给自己店铺下单、评价、点星 2、成本很低:都是自己准备一些资料进行注册的,因此成本也是比较可控的。 3、自己管理更加安全可控:每个账号都是独…...
OCR名片识别:手机电脑大比拼,哪个更胜一筹?
随着名片的使用越来越普遍,如何快速准确地识别名片信息成为很多人的需求。而名片OCR识别技术正好能够满足这一需求,但是面对不同的识别方案,很多人会感到困惑。本文将介绍名片OCR识别的方案选择,分别介绍手机和电脑上的识别方案&a…...
深度学习OCR中文识别 - opencv python 计算机竞赛
文章目录 0 前言1 课题背景2 实现效果3 文本区域检测网络-CTPN4 文本识别网络-CRNN5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习OCR中文识别系统 ** 该项目较为新颖,适合作为竞赛课题方向,…...
Python(七) 条件控制、循环语句
程序员的公众号:源1024,获取更多资料,无加密无套路! 最近整理了一波电子书籍资料,包含《Effective Java中文版 第2版》《深入JAVA虚拟机》,《重构改善既有代码设计》,《MySQL高性能-第3版》&…...
SpringCloud GateWay自定义过滤器之GatewayFilter和AbstractGatewayFactory
一、GatewayFilter GatewayFilter 是一个简单的接口,用于定义网关过滤器的行为。一个网关过滤器就是一个实现了 GatewayFilter 接口的类,它可以执行在请求进入网关或响应离开网关时的某些操作。过滤器可以用于修改请求或响应,记录日志&#…...
不会英语能学编程吗?0基础学编程什么软件好?
不会英语能学编程吗?0基础学编程什么软件好? 给大家分享一款中文编程工具,零基础轻松学编程,不需英语基础,编程工具可下载。 这款工具不但可以连接部分硬件,而且可以开发大型的软件,象如图这个…...
程序员副业接单做私活避坑指南
不建议大家在接单这个事情上投入太大精力,如果你“贼心不改”,建议大家以比较随缘的方式对待这件事情。 接单平台 下文是接单平台,内容来自知乎,转载过来的原因有2个: 方便大家了解这些平台各自的优势,可以…...
day57
今日内容概要 模板层 模板之过滤器 模板之标签(if else for) 模板之继承 导入模板 模型层 单表的操作 十几种常见的查询方法 基于下划线的查询方法 外键字段的增删改查 正反向查询(多表跨表) 模板之过滤器 语法: {{obj|filter__name:param}} 变量名字|…...
以太坊链多节点本地化【最详细的部署搭建及维护文档】
文章目录 一、维护人员素养1.1 岗位技能1.2 人员素质二、区块链节点及区块链浏览器搭建2.1 编写说明2.1.1 文档说明2.1.2 配置信息2.1.3 部署文档信息2.2 node环境安装2.2.1 基础命令安装2.2.2 安装node2.3 centos7 部署docker环境2.3.1 卸载旧版本2.3.2 使用 yum 安装2.3.3 使…...
微服务架构演进
系统架构演变 没有最好的架构,只有最合适的架构;架构发展过程:单体架构》垂直架构》SOA 面向服务架构》微服务架构;推荐看看《淘宝技术这十年》; 单体架构 互联网早期,一般的网站应用流量较小࿰…...
BUUCTF 九连环 1
BUUCTF:https://buuoj.cn/challenges 题目描述: 下载附件,解压得到一张.jpg图片。 密文: 解题思路: 1、一张图片,典型的图片隐写。放到Kali中,使用binwalk检测,确认图片中隐藏zip压缩包。 使…...
编码自动化:使用MybatisX初体验,太爽了!
使用Mybatis当前最火的插件:MybatisX。 在IDEA中安装MyBatisX插件。 该插件主要功能如下: 生成mapper xml文件 快速从代码跳转到mapper及从mapper返回代码 mybatis自动补全及语法错误提示 集成mybatis Generate GUI界面 根据数据库注解,…...
大数据-之LibrA数据库系统告警处理(ALM-12047 网络读包错误率超过阈值)
告警解释 系统每30秒周期性检测网络读包错误率,并把实际错误率和阈值(系统默认阈值0.5%)进行比较,当检测到网络读包错误率连续多次(默认值为5)超过阈值时产生该告警。 用户可通过“系统设置 > 阈值配置…...
JSP 报错 Cannot resolve method ‘print(java.lang.String)‘问题解决
这里 我写了一段比较基础的代码 <%// 定义局部变量String message "Hello, JSP!";out.print(message); %>但是 项目跑起来又是可以的 其实就是缺少了 JAR包 依赖 我们 可以在项目环境中找到 pom.xml dependencies标签内 加入 如下代码 <dependency>…...
Linux系统下安装RabbitMQ超简单教程(非详细)(Centos8)
文章目录 一、下载所需安装包二、安装三、启动rabbitmq四、添加远程用户五、图形化访问六、修改rabbitmq的启动端口和管理端口(没有这个需求就不用看了)七、需要注意版本问题可能遇到的错误和解决方式version GLIBC_2.34 类型错误undefined function rab…...
2024江苏专转本流程与时间节点
2024江苏专转本考生,提前看一下转本的流程与时间节点!适用于江苏三年制、五年一贯制专转本考试: 1. 专转本工作通知(2023年12月上旬) 若无特殊情况,到12月中旬,江苏省教育厅会发布关于做好2024…...
全国各区县日照时长数据,逐月数据均有!
今天给大家分享的是全国各区县日照时长月数据,包括不同月份不同地区的日照时长。这些数据可以帮助我们了解不同地区在不同月份的日照情况,为能源利用、农业生产和气候变化研究提供参考。 基本信息 数据名称: 全国各区县日照时长月数据 数据格式: shpex…...
candence出现no connect property onpin,,,,错误,该怎么办?
原因是上面有引脚添加了 属性no connect,但依然连接了网络,这个时候需要把线剪切,然后看到引脚上有个X, 解决方法: 工具栏"place >no connect "X 再连上线,再生成网标的时候, 就不报错了…...
Elasticsearch:Lucene 中引入标量量化
作者:BENJAMIN TRENT 我们如何将标量量化引入 Lucene。 Lucene 中的自动字节量化 虽然 HNSW 是一种强大而灵活的存储和搜索向量的方法,但它确实需要大量内存才能快速运行。 例如,查询 768 维的 1MM float32 向量大约需要 1,000,000*4*(7681…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
