当前位置: 首页 > news >正文

爬虫学习案例5

爬取b站一个视频

罗翔老师某一个视频很刑

单个完整代码:

安装依赖库

pip install lxml requests 
import osimport requests
import re
from lxml import etree
import json
# 格式化展开输出
from  pprint import pprint
# 导入进程模块
import subprocess
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36','cookie': '自己的cookid'
}
url = "https://www.bilibili.com/video/BV1N8qnYeEi3/"
resp = requests.get(url, headers=headers)
html = resp.text
# 提取数据
tree = etree.HTML(html)
title = tree.xpath("/html/body/div[2]/div[2]/div[1]/div[1]/div[1]/div/h1/text()")[0].replace(" ","")
# 视频信息
video_info = re.findall('<script>window.__playinfo__=(.*?)</script>',html)
# 转成json字典
json_data = json.loads(video_info[0])
pprint(json_data)
# 音频链接地址
audio_url = json_data['data']['dash']['audio'][0]['baseUrl']
# print(audio_url)
# 视频链接地址
video_url = json_data['data']['dash']['video'][0]['baseUrl']
# print(video_url)
# 开始下载
os.makedirs("temp",exist_ok=True)
audio_content = requests.get(audio_url,headers).content
video_content = requests.get(video_url,headers).content
with open("temp\\"+title+".mp3",'wb') as audio:audio.write(audio_content)
print("音频下载完成")
with open("temp\\"+title+".mp4",'wb') as video:video.write(video_content)
print("视频下载完成")
# 合并
os.makedirs("data",exist_ok=True) # 合并后的视频存放目录ffmpeg_path = r"D:\env\ffmpeg-2024-12-11-git-a518b5540d-full_build\bin\ffmpeg.exe" # 修改为自己ffmpeg.exe目录
cmd = f'"{ffmpeg_path}" -i temp\\{title}.mp4 -i temp\\{title}.mp3 -c:v copy -c:a aac -strict experimental data\\{title}.mp4'
subprocess.run(cmd, shell=True)

获取思路:

打开network,看到与众不同的图标,音频和视频就在里面
在这里插入图片描述
这个与众不同的请求头和我们访问的url是一样的
在这里插入图片描述
查看页面的源代码,发现
在这里插入图片描述
所以请求url,获取页面,采集数据的链接,下一步下载到本地,然后把音频和视频合并成一个。
提取打印出video_info信息
在这里插入图片描述
pprint格式化输出video_info
在这里插入图片描述
with open写出到本地:
在这里插入图片描述
合并

下载ffmpeg

ffmpeg官网
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
不要用谷歌浏览器下载,很慢的,换其他浏览器
配置一下path,把bin目录粘贴过来就可以
在这里插入图片描述
测试安装成功cmd命令:ffmpeg -version
在这里插入图片描述

PotPlayer:不支持S/W HEVC(H265)解码

在这里插入图片描述
下载下来:默认安装即可(一直下一步)
PotPlayer:不支持S/W HEVC(H265)解码 的解决办法来源自:大佬
https://github.com/Nevcairiel/LAVFilters/releases
在这里插入图片描述
再重新打开data目录下的视频可以了
在这里插入图片描述

在这里插入图片描述

爬取多个视频

思路:

需要获取到对应的bvid,(bvid在search请求中获取)
发起请求:url = f"https://www.bilibili.com/video/变量bvid/"
循环每一项,就是每个视频的下载

接下来需要为这个search请求构建请求参数,请求头,cookie

baseUrl = "https://space.bilibili.com/3493110839511225/video" # 获取那个up主空间的视频
headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36","cookie": "自己的cookie","referer": baseUrl #防盗链来源
}
link = "https://api.bilibili.com/x/space/wbi/arc/search" # search请求

在这里插入图片描述

在这里插入图片描述
接下来需要请求参数,全部都要
在这里插入图片描述

PyCharm批量替换的快捷键 ctrrl+r
使用正则批量添加参数的引号

(.*?): (.*)
'$1': '$2',

在这里插入图片描述
如果需要获取其他up主视频
修改完整源码的:baseUrl,headers的cookie值,params参数

多个视频完整源码:

# 优化,标题重复了,导致文件重复
import os
import timeimport requests
import re
from lxml import etree
import json
from pprint import pprint
import subprocess
from tqdm import tqdm
from datetime import  datetimebaseUrl = "https://space.bilibili.com/3493110839511225/video"
headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36","cookie": "自己cookie","referer": baseUrl
}
link = "https://api.bilibili.com/x/space/wbi/arc/search"
params = {
'mid': '1789878166',
'ps': '30',
'tid': '0',
'pn': '1',
'keyword':'',
'order': 'pubdate',
'platform': 'web',
'web_location': '1550101',
'order_avoided': 'true',
'dm_img_list': '[]',
'dm_img_str': 'V2ViR0wgMS4wIChPcGVuR0wgRVMgMi4wIENocm9taXVtKQ',
'dm_cover_img_str': 'QU5HTEUgKEludGVsLCBJbnRlbChSKSBJcmlzKFIpIFhlIEdyYXBoaWNzICgweDAwMDBBN0EwKSBEaXJlY3QzRDExIHZzXzVfMCBwc181XzAsIEQzRDExKUdvb2dsZSBJbmMuIChJbnRlbC',
'dm_img_inter': '{"ds":[{"t":2,"c":"Y2xlYXJmaXggZy1zZWFyY2ggc2VhcmNoLWNvbnRhaW5lcg","p":[1782,44,589],"s":[437,899,1290]},{"t":2,"c":"d3JhcHBlcg","p":[795,35,1350],"s":[227,4206,3506]}],"wh":[4506,3752,112],"of":[301,602,301]}',
'w_webid': 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzcG1faWQiOiIwLjAiLCJidXZpZCI6IkMwRTlFOEZGLTExN0ItNkIxOS03MEExLUI3OTQ5NkY4NDQ1NDc0NTA0aW5mb2MiLCJ1c2VyX2FnZW50IjoiTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzEzMS4wLjAuMCBTYWZhcmkvNTM3LjM2IiwiYnV2aWRfZnAiOiJDMEU5RThGRi0xMTdCLTZCMTktNzBBMS1CNzk0OTZGODQ0NTQ3NDUwNGluZm9jIiwiYmlsaV90aWNrZXQiOiJmNDM3MDQ2Y2Y4ODkwNzNhMmQyODIyODkxMWVmODI0OCIsImNyZWF0ZWRfYXQiOjE3MzQxNjA3ODEsInR0bCI6ODY0MDAsInVybCI6Ii8xNzg5ODc4MTY2L3ZpZGVvIiwicmVzdWx0Ijoibm9ybWFsIiwiaXNzIjoiZ2FpYSIsImlhdCI6MTczNDE2MDc4MX0.X9iXzZ0ajsvrAqrs53IbCZ4kE9-uQ20qdI1rxRo9ylGqHrCp7tjwq4aHma1eZ2VMBGo7fKGEyK_4I0bYYprFhstC5H2vEitrBiZ3WxCv43p-dDUiK_wiOflwKIW2rMDw5C0Hd1fd0cq3tfiHLALanKLgsr8EpYC8hpeIw_KmimZJQa3c4sb2Ic8aIzxEC_kzVWFFeDriU8VF8OYBDjspLAHwwKkucPteE10IOMZ8ONnmxWKzyTTf_hwf5dtFbAUY1oeozUWKAFdsTiYpTlD2vn_7zBeFUQCmfXUoB17z9BbGdtegQYONSDD1awDHZ7cIm0ZoH5FP8R1VzGBMteSEmg',
'w_rid': '5ebd3bc3f9edb242cb19bc1618b36538',
'wts': '1734160784',
}jsonData = requests.get(url=link, params=params, headers=headers).json()
v_list = jsonData['data']['list']['vlist']
# pprint(v_list)page = 0
for v in v_list:page += 1bvid = v['bvid']url = f"https://www.bilibili.com/video/{bvid}/"resp = requests.get(url, headers=headers, timeout=120)html = resp.texttree = etree.HTML(html)title = tree.xpath("/html/body/div[2]/div[2]/div[1]/div[1]/div[1]/div/h1/text()")[0].replace(" ", "")# 获取当前时间戳timestamp = datetime.now().strftime("%Y%m%d%H%M%S")unique_title = f"{title}_{timestamp}"video_info = re.findall('<script>window.__playinfo__=(.*?)</script>', html)json_data = json.loads(video_info[0])audio_url = json_data['data']['dash']['audio'][0]['baseUrl']video_url = json_data['data']['dash']['video'][0]['baseUrl']os.makedirs("temp1", exist_ok=True)def download_file(url, filename):response = requests.get(url, headers=headers, stream=True, timeout=120)total_size = int(response.headers.get('content-length', 0))with open(filename, 'wb') as file, tqdm(desc=filename,total=total_size,unit='B',unit_scale=True,unit_divisor=1024,) as bar:for data in response.iter_content(chunk_size=1024):size = file.write(data)bar.update(size)try:audio_filename = f"temp1/{unique_title}.mp3"download_file(audio_url, audio_filename)print("音频下载完成")video_filename = f"temp1/{unique_title}.mp4"download_file(video_url, video_filename)print("视频下载完成")print(title)os.makedirs("data1", exist_ok=True)ffmpeg_path = r"D:\env\ffmpeg-2024-12-11-git-a518b5540d-full_build\bin\ffmpeg.exe" #修改为自己的ffmpeg.exe目录cmd = f'"{ffmpeg_path}" -i {video_filename} -i {audio_filename} -c:v copy -c:a aac -strict experimental data1/{unique_title}.mp4'subprocess.run(cmd, shell=True, check=True)print(f"第{page}个视频下载成功")print(f"{unique_title}.mp4")except Exception as e:print(f"下载或合并失败: {e}")time.sleep(10)

在这里插入图片描述

在这里插入图片描述
完整代码感觉就这个下载进度条函数不太好理解,所以这里用AI解释了一下代码,以供参考学习!看得懂可以忽略不计。

    def download_file(url, filename):response = requests.get(url, headers=headers, stream=True, timeout=120)total_size = int(response.headers.get('content-length', 0))with open(filename, 'wb') as file, tqdm(desc=filename,total=total_size,unit='B',unit_scale=True,unit_divisor=1024,) as bar:for data in response.iter_content(chunk_size=1024):size = file.write(data)bar.update(size)

response = requests.get(url, headers=headers, stream=True, timeout=120)
功能: 使用 requests.get 方法发送 HTTP GET 请求以获取文件内容。
参数:
url: 目标文件的 URL。
headers: 请求头信息,通常用于模拟浏览器访问或其他身份验证。
stream=True: 设置为 True 表示不立即下载整个文件,而是以流的形式逐步下载。
timeout=120: 设置请求超时时间为 120 秒。

total_size = int(response.headers.get(‘content-length’, 0))
功能: 从响应头中获取文件的总大小(以字节为单位)。
细节:
response.headers.get(‘content-length’, 0): 尝试从响应头中获取 Content-Length 字段的值,如果不存在则返回默认值 0。
int(…): 将获取到的字符串形式的大小转换为整数。

with open(filename, ‘wb’) as file, tqdm(
desc=filename,
total=total_size,
unit=‘B’,
unit_scale=True,
unit_divisor=1024,
) as bar:
功能: 打开一个文件用于写入二进制数据,并创建一个 tqdm 进度条来显示下载进度。
参数:
open(filename, ‘wb’): 以二进制写模式打开文件。
tqdm(…): 创建一个进度条对象。
desc=filename: 设置进度条的描述信息为文件名。
total=total_size: 设置进度条的总长度为文件的总大小。
unit=‘B’: 设置进度条的单位为字节。
unit_scale=True: 允许进度条自动缩放单位(例如,从字节到千字节、兆字节等)。
unit_divisor=1024: 设置单位缩放的基数为 1024。

    for data in response.iter_content(chunk_size=1024):size = file.write(data)bar.update(size)

功能: 逐块下载文件内容并写入本地文件,同时更新进度条。
细节:
response.iter_content(chunk_size=1024): 以 1024 字节(即 1 KB)为一块逐步读取响应内容。
size = file.write(data): 将读取到的数据块写入文件,并返回实际写入的字节数。
bar.update(size): 更新进度条,显示已下载的字节数。
总结
这个函数的主要目的是从指定的 URL 下载文件,并使用 tqdm 库在控制台中显示下载进度。通过这种方式,用户可以直观地看到文件下载的进度,从而更好地了解下载状态。

运行效果

在这里插入图片描述
这个代码还是有所欠缺的。只能爬取up主一个一个的视频,如果是合集里面的,默认获取合集第一个视频
在这里插入图片描述

相关文章:

爬虫学习案例5

爬取b站一个视频 罗翔老师某一个视频很刑 单个完整代码&#xff1a; 安装依赖库 pip install lxml requests import osimport requests import re from lxml import etree import json # 格式化展开输出 from pprint import pprint # 导入进程模块 import subprocess head…...

视频监控汇聚平台方案设计:Liveweb视频智能监管系统方案技术特点与应用

随着科技的发展&#xff0c;视频监控平台在各个领域的应用越来越广泛。然而&#xff0c;当前的视频监控平台仍存在一些问题&#xff0c;如视频质量不高、监控范围有限、智能化程度不够等。这些问题不仅影响了监控效果&#xff0c;也制约了视频监控平台的发展。 为了解决这些问…...

ansible自动化运维(三)jinja2模板roles角色管理

相关文章ansible自动化运维&#xff08;一&#xff09;简介及清单,模块-CSDN博客ansible自动化运维&#xff08;二&#xff09;playbook模式详解-CSDN博客ansible自动化运维&#xff08;四&#xff09;运维实战-CSDN博客 三.Ansible jinja2模板 Jinja2是Python的全功能模板引…...

队列+宽搜_429. N 叉树的层序遍历_二叉树最大宽度

429. N 叉树的层序遍历 定义一个队列q&#xff0c;将一层的节点入队&#xff0c;并记录节点个数。根据节点的个数&#xff0c;出队列&#xff0c;并将其孩子入队列。出完队列&#xff0c;队列当前剩余节点的个数就是下次出队列的次数。直到队列为空 /* // Definition for a Nod…...

Windows11安装及使用nvm

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Windows11安装nvm 前言一、简介二、下载三、安装1、双击运行&#xff0c;同意协议&#xff0c;点击Next2、选择nvm安装路径&#xff0c;此路径也是环境变量NVM_HOME的路径&am…...

(一)机器学习 - 入门

数据集 数据集是一组数据的集合&#xff0c;这些数据可以是数值型、文本型、图形型等多种形式。数据集通常用于统计分析、机器学习、科学研究、商业智能等领域&#xff0c;以发现数据中的模式、趋势和关联性。 数据集的组成&#xff1a; 变量&#xff08;Variables&#xff09;…...

【解决】k8s使用kubeadm初始化集群失败问题整理

执行提示命令&#xff0c;查看报错信息 journalctl -xeu kubelet1、错误&#xff1a;running with swap on is no 报错 "command failed" err"failed to run Kubelet: running with swap on is no 解决&#xff1a; swap未禁用&#xff0c;需要禁用swap&…...

apache-dubbo

dubbo 文档地址 dubbo 官方文档地址 https://dubbo.apache.org/zh-cn/docs/user/references/api.html nacos 官方文档地址 https://nacos.io/zh-cn/docs/quick-start.html nacos下载地址 https://github.com/alibaba/nacos/releases/download/2.3.0/nacos-server-2.3.0.…...

ECharts柱状图-柱图2,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个柱状图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供…...

【新人系列】Python 入门(十六):正则表达式

✍ 个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4dd; 专栏地址&#xff1a;https://blog.csdn.net/newin2020/category_12801353.html &#x1f4e3; 专栏定位&#xff1a;为 0 基础刚入门 Python 的小伙伴提供详细的讲解&#xff0c;也欢迎大佬们…...

HTML综合

一.HTML的初始结构 <!DOCTYPE html> <html lang"en"><head><!-- 设置文本字符 --><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><!-- 设置网页…...

孚盟云 MailAjax.ashx SQL注入漏洞复现

0x01 产品简介 上海孚盟软件有限公司是一家外贸SaaS服务提供商,也是专业的外贸行业解决方案专业提供商。 全新的孚盟云产品,让用户可以用云模式实现信息化管理,让用户的异地办公更加流畅,大大降低中小企业在信息化上成本,用最小的投入享受大型企业级别的信息化服务,主要…...

解决“VMware虚拟机报Intel VT-x”错误

今天&#xff0c;在windows系统上&#xff0c;打开VMware WorkStation v15软件里的虚拟机&#xff0c;弹出"Intel VT-x处于禁用状态"错误&#xff0c;如图(1)所示&#xff1a; 图(1) 虚拟机报"Intel VT-x"错误 问题原因&#xff1a;当前电脑的BIOS没有开启…...

NiceGUI `ui.table` 基础

NiceGUI ui.table 基础 ui.table 是 NiceGUI 提供的一个组件&#xff0c;用于在页面上展示数据表格 基本概念 官方简介 A table based on Quasar’s QTable component. 参数参考rows:list of row objects; 行对象列表columns:list of column objects (defaults to the colu…...

分布式 Raft算法 总结

前言 相关系列 《分布式 & 目录》《分布式 & Raft算法 & 总结》《分布式 & Raft算法 & 问题》 参考文献 《Raft一致性算法论文译文》《深入剖析共识性算法 Raft》 简介 Raft 木筏是一种基于日志复制实现的分布式容错&一致性算法。在Raft算法…...

C++ 中面向对象编程如何实现动态绑定?

在 C 中&#xff0c;动态绑定&#xff08;Dynamic Binding&#xff09;是通过 虚函数&#xff08;virtual function&#xff09; 和 多态性&#xff08;polymorphism&#xff09; 来实现的。这是面向对象编程的重要特性之一&#xff0c;它允许程序在运行时根据对象的实际类型调…...

微服务-01

1.认识微服务 1.1 单体架构 单体架构&#xff08;monolithic structure&#xff09;&#xff1a;顾名思义&#xff0c;整个项目中所有功能模块都在一个工程中开发&#xff1b;项目部署时需要对所有模块一起编译、打包&#xff1b;项目的架构设计、开发模式都非常简单。 当项目…...

这是一个vue3 + scss的数字滚动效果

介绍: 当数字变化时&#xff0c;只改变变化的数字位&#xff0c;其余的不变&#xff0c;可以递增、递减、骤变、负数也可以&#xff0c;但是样式要根据具体的项目需求去改&#xff1b; 效果1、增加数字&#xff1a; 效果2、减少数字&#xff1a; 使用方法&#xff1a; <te…...

数字证书管理工具 openssl keytool

OPENSSL 命令 openssl command [ command_opts ] [ command_args ] 常用command: version 用于查看版本信息 enc 用于加解密 ciphers 列出加密套件 genrsa 用于生成私钥 -des|-des3|-idea&#xff1a;用来加密私钥文件的三种对称加密算法。 rsa …...

Polars数据聚合与旋转实战教程

在这篇博文中&#xff0c;我们的目标是解决数据爱好者提出的一个常见问题&#xff1a;如何有效地从Polars DataFrame中创建汇总视图&#xff0c;以便在不同时间段或类别之间轻松进行比较。我们将使用一个实际的数据集示例来探索实现这一目标的各种方法。 Polars简介 Polars 是…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

《Docker》架构

文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器&#xff0c;docker&#xff0c;镜像&#xff0c;k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...

沙箱虚拟化技术虚拟机容器之间的关系详解

问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西&#xff0c;但是如果把三者放在一起&#xff0c;它们之间到底什么关系&#xff1f;又有什么联系呢&#xff1f;我不是很明白&#xff01;&#xff01;&#xff01; 就比如说&#xff1a; 沙箱&#…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...