爬虫学习案例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.mzph.cn/bicheng/64150.shtml

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

相关文章

【深度学习】 零基础介绍卷积神经网络(CNN)

零基础介绍 卷积神经网络&#xff08;CNN&#xff0c;Convolutional Neural Network&#xff09;是深度学习中的一种神经网络&#xff0c;特别擅长处理图像和视频等有空间结构的数据。 假设我们在做一个“照片分类”的任务&#xff0c;比如判断一张照片中是猫还是狗。下面用一…

【计算机组成原理】实验二:通用寄存器单元实验

实验二&#xff1a;通用寄存器单元实验 一、实验目的 了解通用寄存器的组成和硬件电路&#xff0c;利用通用寄存器实现数据的置数、左移、右移等功能。 二、实验内容 数据输入通用寄存器 寄存器内容无进位位左移实验 寄存器内容无进位位右移实验 三、实验步骤和结果 实…

4G模块详解

在之前的教程中&#xff0c;无线通信技术我们学习了蓝牙和 WiFi&#xff0c;今天我们要来学习 4G。 4G 模块在距离上有个突破&#xff0c;它不像蓝牙短距离&#xff0c;也不像 WiFi 只能在局域网&#xff0c;4G 模块可使用户无论在哪&#xff0c;只要有 4G 网络信号覆盖&#…

Visual Studio 使用 GitHub Copilot 聊天

&#x1f380;&#x1f380;&#x1f380;【AI辅助编程系列】&#x1f380;&#x1f380;&#x1f380; Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码Visual Studio 安装和管理 GitHub CopilotVisual Studio 使用 GitHub Copilot 扩展Visual Studio 使用 GitHu…

TimerPickerDialog组件的用法

文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了Snackbar Widget相关的内容,本章回中将介绍TimePickerDialog Widget.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的TimePickerDialog是一种弹出窗口,只不过窗口的内容固定显示为时间,它主…

Linux高并发服务器开发 第四天(wc/whoami命令 权限修改chmod 添加/删除用户(组) 切换用户 修改文件所有者/所属组 查找/过滤)

目录 1.wc和whoami命令 1.1wc命令 1.2whoami命令 2.用户权限/用户/用户组 2.1修改文件权限chmod 2.1.1文字设定法 2.1.2数字设定法 2.2添加删除新用户和新用户组 2.3切换用户 2.4修改文件所有者和所属组 2.4.1修改所有者 2.4.2修改所属组 3.查找和过滤 3.1find—…

微服务架构导学

一. 什么是微服务 微服务是一个软件架构风格&#xff0c;将一个大型的项目拆分成多个小项目&#xff0c;每个项目都被称为一个微服务&#xff0c;通过多个微服务共同组成一个大的项目。 二. 单体架构和微服务架构 单体架构 将整个项目的功能、模块全部堆积在一个项目中 优点&am…

【kubernetes】kubectl get nodes报NotReady

目录 1. 说明2. 问题描述3. kube-flannel.yml 1. 说明 1.这里k8s的版本是v1.17.4。2.若kube-flannel.yml中的镜像拉取不下来&#xff0c;可以下载本文章的文件资源&#xff0c;手动docker load -i ***.tar的方式。3.v1.17.4的kube-flannel.yml参考下面代码。4.通过kubectl get…

web实操7——ServletContext

概念 和服务器通信 功能 解释说明&#xff1a; mime&#xff1a;互联网中一种文件的类型&#xff0c;可以用servletContext对象来获取。 域对象&#xff1a;用来共享数据&#xff0c;里面有一些get,set,removeAttribute,只要搞清楚ServletContext对象的域的范围是什么 如何…

LLMC:大语言模型压缩工具的开发实践

关注&#xff1a;青稞AI&#xff0c;学习最新AI技术 青稞Talk主页&#xff1a;qingkelab.github.io/talks 大模型的进步&#xff0c;正推动我们向通用人工智能迈进&#xff0c;然而庞大的计算和显存需求限制了其广泛应用。模型量化作为一种压缩技术&#xff0c;虽然可以用来加速…

舌头分割数据集labelme格式2557张1类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;2557 标注数量(json文件个数)&#xff1a;2557 标注类别数&#xff1a;1 标注类别名称:["tongue"] 每个类别标注的框数&#xff1…

测试工程师八股文03|Python编程题

一、题目 1、合并两个数组 class Solution:def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:nums1[m:] nums2nums1.sort()2、判断链表中是否有环 class Solution:def hasCycle(self, head: ListNode) -> bool:seen set()while head:if…

MyBatis-Plus 基础

教程 视频教程&#xff1a;https://www.bilibili.com/video/BV1Xu411A7tL 详细文档&#xff1a;https://b11et3un53m.feishu.cn/wiki/PsyawI04ei2FQykqfcPcmd7Dnsc 常见注解 MybatisPlus就是根据PO实体的信息来推断出表的信息&#xff0c;从而生成SQL的。默认情况下&#xf…

VMware Workstation Pro 17 下载 以及 安装 Ubuntu 20.04.6 Ubuntu 启用 root 登录

1、个人免费版本 VMware Workstation Pro 17 下载链接怎么找&#xff1f;直接咕咕 VMware 找到如下链接。链接如下&#xff1a;Workstation 和 Fusion 对个人使用完全免费&#xff0c;企业许可转向订阅 - VMware 中文博客 点进去链接之后你会看到如下&#xff0c;注意安装之后仍…

深度学习——激活函数、损失函数、优化器

深度学习——激活函数、损失函数、优化器 1、激活函数1.1、一些常见的激活函数1.1.1、sigmoid1.1.2、softmax1.1.3、tanh1.1.4、ReLU1.1.5、Leaky ReLU1.1.6、PReLU1.1.7、GeLU1.1.8、ELU 1.2、激活函数的特点1.2.1、非线性1.2.2、几乎处处可微1.2.3、计算简单1.2.4、非饱和性1…

智慧政务数据中台建设及运营解决方案

数据中台&#xff1a;政府数字化转型的引擎 数据中台作为政府数字化转型的核心驱动力&#xff0c;起源于美军的作战体系&#xff0c;强调高效、灵活与强大。它不仅促进了政府决策的科学性&#xff0c;还推动了政府服务的精细化与智能化。 数据中台的应用场景&#xff1a;数字…

计算机毕设-基于springboot的社区居民诊疗健康管理系统的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

day11 性能测试(4)——Jmeter使用(黑马的完结,课程不全)直连数据库+逻辑控制器+定时器

【没有所谓的运气&#x1f36c;&#xff0c;只有绝对的努力✊】 目录 1、复习 1.1 断言&#xff08;3种&#xff09; 1.2 关联&#xff08;3种&#xff09; 1.3 录制脚本 2、Jmeter直连数据库 2.1 直连数据库——使用场景 2.2 直连数据库——操作步骤 2.2.1 案例1&…

React的状态管理库-Redux

核心思想&#xff1a;单一数据源、状态是只读的、以及使用纯函数更新状态。 组成部分 Store&#xff08;存储&#xff09; 应用的唯一状态容器&#xff0c;存储整个应用的状态树,使用 createStore() 创建。 getState()&#xff1a;获取当前状态。dispatch(action)&#xff…

解决MAC装win系统投屏失败问题(AMD显卡)

一、问题描述 电脑接上HDMI线后&#xff0c;电脑上能显示有外部显示器接入&#xff0c;但是外接显示器无投屏画面 二、已测试的方法 1 更改电脑分辨&#xff0c;结果无效 2 删除BootCamp&#xff0c;结果无效 3更新电脑系统&#xff0c;结果无效 4 在设备管理器中&#…