爬虫学习案例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主一个一个的视频,如果是合集里面的,默认获取合集第一个视频
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/490373.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win服务器的架设、windows server 2012 R2 系统的下载与安装使用

文章目录 windows server 2012 R2 系统的下载与安装使用1 windows server 2012 的下载2 打开 VMware 虚拟机软件&#xff08;1&#xff09;新建虚拟机&#xff08;2&#xff09;设置虚拟机&#xff08;3&#xff09;打开虚拟机 windows server 2012&#xff08;4&#xff09;进…

【51单片机】矩阵按键快速上手

51单片机矩阵按键是一种在单片机应用系统中广泛使用的按键排列方式&#xff0c;特别适用于需要多个按键但I/O口资源有限的情况。以下是对51单片机矩阵按键的详细介绍&#xff1a; 一、矩阵按键的基本概念 ‌定义‌&#xff1a;矩阵按键&#xff0c;又称行列键盘&#xff0c;是…

steel-browser - 专为AI应用构建的开源浏览器自动化 API

Steel是一个开源浏览器 API&#xff0c;可以轻松构建与 Web 交互的 AI 应用程序和代理。您无需从头开始构建自动化基础设施&#xff0c;而是可以专注于 AI 应用程序&#xff0c;而 Steel 会处理复杂性。 2300 Stars 99 Forks 4 Issues 5 贡献者 Apache-2.0 License TypeScript …

C# 与PLC数据交互

点击跳转下载地址 点击跳转胡工科技官网

Python中实现YOLO目标检测

文章目录 Python中实现YOLO目标检测一、引言二、环境准备1、安装依赖 2、下载预训练模型三、目标检测1、图像检测2、视频检测 四、使用示例1、轨迹追踪 五、总结 Python中实现YOLO目标检测 一、引言 YOLO&#xff08;You Only Look Once&#xff09;是一种流行的实时目标检测…

Android实现RecyclerView边缘渐变效果

Android实现RecyclerView边缘渐变效果 1.前言&#xff1a; 是指在RecyclerView中实现淡入淡出效果的边缘效果。通过这种效果&#xff0c;可以使RecyclerView的边缘在滚动时逐渐淡出或淡入&#xff0c;以提升用户体验。 2.Recyclerview属性&#xff1a; 2.1、requiresFading…

汽车免拆诊断案例 | 2014款保时捷卡宴车发动机偶尔无法起动

故障现象 一辆2014款保时捷卡宴车&#xff0c;搭载3.0T 发动机&#xff0c;累计行驶里程约为18万km。车主反映&#xff0c;发动机偶尔无法起动。 故障诊断 接车后试车&#xff0c;发动机起动及运转均正常。用故障检测仪检测&#xff0c;发动机控制单元&#xff08;DME&#x…

Hadoop生态圈框架部署(十一)- Sqoop安装与配置

文章目录 前言一、Sqoop安装与配置&#xff08;手动安装配置&#xff09;1. 下载Sqoop安装包并上传到Linux1.1 下载1.2 上传 2. 解压Sqoop安装包2.1 解压2.2 重命名 3. 配置Sqoop3.1 修改 sqoop-env.sh 配置文件3.2 配置jar包3.2.1 配置MySQL驱动jar包3.2.2 配置commons-lang-2…

Jenkins与SonarQube持续集成搭建及坑位详解

Jenkins和SonarQube都是软件开发过程中常用的工具,它们在代码管理、构建、测试和质量管理方面发挥着重要作用。以下是关于Jenkins与SonarQube的作用及整合步骤环境搭建的详细解释: 一、Jenkins与SonarQube的作用 Jenkins: Jenkins是一个开源的持续集成和交付工具,它可以帮…

Linux驱动开发(13):输入子系统–按键输入实验

计算机的输入设备繁多&#xff0c;有按键、鼠标、键盘、触摸屏、游戏手柄等等&#xff0c;Linux内核为了能够将所有的输入设备进行统一的管理&#xff0c; 设计了输入子系统。为上层应用提供了统一的抽象层&#xff0c;各个输入设备的驱动程序只需上报产生的输入事件即可。 下…

关于Postgresql旧版本安装

抛出问题 局点项目现场&#xff0c;要求对如下三类资产做安全加固&#xff0c;需要在公司侧搭建测试验证环境&#xff0c;故有此篇。 bclinux 8.2 tomcat-8.5.59 postgrel -11 随着PG迭代&#xff0c;老旧版本仅提供有限维护。如果想安装老版本可能就要费劲儿一些。现在&…

继电器控制与C++编程:实现安全开关控制的技术分享

在现代生活中,继电器作为一种重要的电气控制元件,在电气设备的安全控制中起到了至关重要的作用。通过低电流控制高电流,继电器能够有效地隔离控制电路与被控设备,从而保障使用者的安全。本项目将介绍如何通过树莓派Pico与继电器模块结合,使用C++编程实现继电器的控制。 一…

时序论文31|NIPS24自注意力机制真的对时序预测任务有效吗?

论文标题&#xff1a;Are Self-Attentions Effective for Time Series Forecasting? 论文链接&#xff1a;https://arxiv.org/pdf/2409.18696 代码链接&#xff1a;https://github.com/dongbeank/CATS 前言 本文将重点转向探究自注意力机制在其中的有效性&#xff0c;提出…

ip_done

文章目录 路由结论 IP分片 数据链路层重谈Mac地址MAC帧报头局域网的通信原理MSS&#xff0c;以及MAC帧对上层的影响ARP协议 1.公司是不是这样呢? 类似的要给运营商交钱&#xff0c;构建公司的子网&#xff0c;具有公司级别的入口路由器 2&#xff0e;为什么要这样呢?? IP地…

计算机网络错题

文章目录 码分复用透明传输差错检测停止-等待协议回退N帧协议CSMA/CD协议以太网交换机Vlanip地址的无分类编制方法ip地址的应用规划ip数据包的发送和转发过程路由信息协议IPI2016201720202022 2.5信道 码分复用 透明传输 差错检测 停止-等待协议 回退N帧协议 CSMA/CD协议 以太网…

2024 年 9 月区块链游戏研报:行业回暖,Telegram 游戏引发热潮

作者&#xff1a;Stella L (stellafootprint.network) 数据来源&#xff1a;Footprint Analytics Games Research Page 9 月份&#xff0c;区块链游戏代币的市场总值增长了 29.2%&#xff0c;达到 232 亿美元&#xff0c;日活跃用户&#xff08;DAU&#xff09;数量上升了 1…

Https身份鉴权(小迪网络安全笔记~

附&#xff1a;完整笔记目录~ ps&#xff1a;本人小白&#xff0c;笔记均在个人理解基础上整理&#xff0c;若有错误欢迎指正&#xff01; 5.2 Https&身份鉴权 引子&#xff1a;上一篇主要对Http数据包结构、内容做了介绍&#xff0c;本篇则聊聊Https、身份鉴权等技术。 …

ORACLE逗号分隔的字符串字段,关联表查询

使用场景如下&#xff1a; oracle12 以前的写法&#xff1a; selectt.pro_ids,wm_concat(t1.name) pro_names from info t,product t1 where instr(,||t.pro_ids|| ,,,|| t1.id|| ,) > 0 group by pro_ids oracle12 以后的写法&#xff1a; selectt.pro_ids,listagg(DIS…

MySQL八股文

MySQL 自己学习过程中的MySQL八股笔记。 主要来源于 小林coding 牛客MySQL面试八股文背诵版 以及b站和其他的网上资料。 MySQL是一种开放源代码的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;使用最常用的数据库管理语言–结构化查询语言&#xff08;SQL&…

使用echarts实现3d柱状图+折线图

以下代码有问题请直接问国内直连GPT/Claude HTML 需要注意threeDchart一定要设置宽度高度&#xff0c;不然图不显示,然后echarts版本不要太低&#xff0c;不然也不显示 <div id"threeDchart" class"threeDchart"></div>js set3DBarChart2(dat…