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

Java爬取哔哩哔哩视频(可视化)

链接:我的讲解视频https://www.bilibili.com/video/BV14e411Q7oG/
本文仅供学术用途

先上图

在这里插入图片描述

代码

爬虫核心

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.gargoylesoftware.htmlunit.*;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.Executor;
import org.apache.commons.exec.PumpStreamHandler;
import org.apache.commons.io.IOUtils;import java.io.*;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;class Spider {public void catchvideo(String url,String addr) throws IOException {//TODO 建立无头浏览器WebClient webClient = new WebClient();webClient.getOptions().setJavaScriptEnabled(false);webClient.getOptions().setCssEnabled(false);webClient.getOptions().setThrowExceptionOnFailingStatusCode(true);webClient.getOptions().setThrowExceptionOnScriptError(true);webClient.addRequestHeader("Referer", "https://www.bilibili.com/index.html");webClient.addRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.40");//TODO 设置请求参数,建立请求WebRequest webRequest = new WebRequest(new URL(url), HttpMethod.GET);//TODO 获取响应体Page page = webClient.getPage(webRequest);WebResponse webResponse = page.getWebResponse();String contentAsString = webResponse.getContentAsString();
//        System.out.println(contentAsString);//TODO 模式匹配找视频总数Pattern pattern = Pattern.compile("<script>window.__INITIAL_STATE__=(.*?);\\(function\\(\\)");Matcher matcher = pattern.matcher(contentAsString);String s = null;if (matcher.find())s = matcher.group(1);JSONObject jsonObject = JSON.parseObject(s);int videonum = jsonObject.getJSONObject("videoData").getIntValue("videos");
//        System.out.println("视频总数" + videonum);//TODO 获取目录名pattern = Pattern.compile("<meta data-vue-meta=\"true\" property=\"og:title\" content=\"(.*?)_哔哩哔哩_bilibili\">");matcher = pattern.matcher(contentAsString);String s1 = null;if (matcher.find())s1 = matcher.group(1);elseSystem.out.println("没有找到");//目录名去除./&*这些字符String content = s1.replaceAll("[/&*_,《》\\s+]", "");
//        System.out.println("目录名" + content);//TODO 建立目录String dir = addr+"\\" + content + "\\";File directory = new File(dir);if (!directory.exists())directory.mkdirs();for (int i = 1; i <= videonum; i++) {//TODO 设置请求参数,建立请求webRequest = new WebRequest(new URL(url + "?p=" + i), HttpMethod.GET);
//            System.out.println(webRequest);//TODO 获取响应体page = webClient.getPage(webRequest);webResponse = page.getWebResponse();contentAsString = webResponse.getContentAsString();//TODO 获取视频链接pattern = Pattern.compile("<script>window.__playinfo__=(.*?)</script>");matcher = pattern.matcher(contentAsString);String s2 = null;if (matcher.find())s2 = matcher.group(1);elseSystem.out.println("没有找到");String videolink = JSON.parseObject(s2).getJSONObject("data").getJSONObject("dash").getJSONArray("video").getJSONObject(0).getString("baseUrl");String audiolink = JSON.parseObject(s2).getJSONObject("data").getJSONObject("dash").getJSONArray("audio").getJSONObject(0).getString("baseUrl");
//            System.out.println("视频下载链接\n" + videolink);
//            System.out.println("音频下载链接\n" + audiolink);//TODO 获取视频名称pattern = Pattern.compile("<title data-vue-meta=\"true\">(.*?)_哔哩哔哩_bilibili</title>");matcher = pattern.matcher(contentAsString);String s3 = null;if (matcher.find())s3 = matcher.group(1);elseSystem.out.println("没有找到");//目录名去除./&*这些字符String videoname = s3.replaceAll("[/&*_,《》\\s+]", "");System.out.println(i + "_________________________" + videoname);String videofile = dir + "tmp_" + videoname + ".mp4";String audiofile = dir + "tmp_" + videoname + ".mp3";//TODO 下载视频webRequest = new WebRequest(new URL(videolink), HttpMethod.GET);page = webClient.getPage(webRequest);webResponse = page.getWebResponse();InputStream inputStream = webResponse.getContentAsStream();OutputStream outputStream = new FileOutputStream(videofile);IOUtils.copy(inputStream, outputStream);inputStream.close();outputStream.close();//TODO 下载音频webRequest = new WebRequest(new URL(audiolink), HttpMethod.GET);page = webClient.getPage(webRequest);webResponse = page.getWebResponse();inputStream = webResponse.getContentAsStream();outputStream = new FileOutputStream(audiofile);IOUtils.copy(inputStream, outputStream);inputStream.close();outputStream.close();//TODO 执行合并命令// 创建命令行CommandLine commandLine = CommandLine.parse("ffmpeg -i " + videofile + " -i " + audiofile + " -c:v copy -c:a aac -strict experimental " + dir + i + "_" + videoname + ".mp4"); // 使用 Windows cmd 命令作为示例// 创建执行器Executor executor = new DefaultExecutor();// 设置输出流处理器(可选)PumpStreamHandler streamHandler = new PumpStreamHandler(System.out, System.err); // 将标准输出和错误输出重定向到控制台executor.setStreamHandler(streamHandler);// 执行命令
//            System.out.println(commandLine);executor.execute(commandLine);
//            int exitValue = executor.execute(commandLine); // 执行命令并获取退出值
//            System.out.println("Exit value: " + exitValue); // 打印退出值(通常为0表示成功)File file = new File(audiofile);file.delete();file = new File(videofile);file.delete();}}
}

可视化代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;public class SwingDemo {public static void main(String[] args) {JFrame jFrame = new JFrame("Swing frame");//设置关闭退出程序jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JPanel panel = new JPanel();jFrame.setContentPane(panel);jFrame.setLocationRelativeTo(null);panel.setLayout(new FlowLayout());JLabel jLabel = new JLabel("下载地址");JTextField jTextField = new JTextField(20);jTextField.setToolTipText("下载地址");JButton download = new JButton("下载");panel.add(jLabel);panel.add(jTextField);panel.add(download);JLabel jLabel1 = new JLabel("文件保存位置");JTextField jTextField1 = new JTextField(20);jTextField1.setText("D:\\videos\\");jTextField1.setToolTipText("文件保存位置");JButton fileaddr = new JButton("选择文件夹");panel.add(jLabel1);panel.add(jTextField1);panel.add(fileaddr);fileaddr.addActionListener(e -> {JFileChooser fileChooser = new JFileChooser();fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);int returnValue = fileChooser.showOpenDialog(null);if (returnValue == JFileChooser.APPROVE_OPTION) {File selectedFile = fileChooser.getSelectedFile();jTextField1.setText(selectedFile.getAbsolutePath());}});download.addActionListener(e -> {String url = jTextField.getText()+"/";String fileAddr = jTextField1.getText();System.out.println(url);System.out.println(fileAddr);try {Spider spider = new Spider();spider.catchvideo(url,fileAddr);} catch (IOException ioException) {ioException.printStackTrace();}});//自适应jFrame.pack();jFrame.setVisible(true);}
}

相关文章:

Java爬取哔哩哔哩视频(可视化)

链接&#xff1a;我的讲解视频https://www.bilibili.com/video/BV14e411Q7oG/ 本文仅供学术用途 先上图 代码 爬虫核心 import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.gargoylesoftware.htmlunit.*; import org.apache.commons.…...

adb shell settings高级指令设置系统属性所有的指令汇总+注释

adb shell settings高级指令设置系统属性所有的指令汇总 目录 系统设置&#xff08;system&#xff09; 安全设置&#xff08;secure&#xff09; 全局设置&#xff08;global&#xff09; 删除设置 帮助 示例应用 屏幕超时时间 自动旋转屏幕 通知光 触觉反馈 动…...

Jmeter- Beanshell语法和常用内置对象(网络整理)

在利用jmeter进行接口测试或者性能测试的时候&#xff0c;我们需要处理一些复杂的请求&#xff0c;此时就需要利用beanshell脚本了&#xff0c;BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法&#xff0c;所以它和java是可以无缝衔接的。beans…...

【C++二级】题一:构造函数

1、常量数据成员的初始化只能通过构造函数的成员初始化列表进行&#xff0c;并且要用关键字const修饰 #include <iostream> using namespace std; class MyClass {int _i;friend void Increment(MyClass& f); public:const int NUM; // ERROR ********found*******…...

C++标准模板库(STL)-list介绍

C标准模板库&#xff08;STL&#xff09;中的list是一个双向链表&#xff0c;它提供了高效的插入、删除和反转操作。list支持随机访问&#xff0c;这意味着我们可以直接访问任何元素&#xff0c;而不需要从头开始遍历链表。此外&#xff0c;list还支持反向迭代&#xff0c;即可…...

Arrays.asList

直接去看原文 原文链接:Arrays.asList() 详解-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- 【1. 要点】 该方法是将数组转化成List集合的方法。 List<String> lis…...

XXXX项目管理目标(某项目实施后基于软件工程的总结)

&#xff08;注&#xff1a;此文作于2007年&#xff0c;算是个缅怀&#xff0c;或者是个吐槽。所有注都是本次发表新加的。原文中的省略号就是原文&#xff0c;并非删减。&#xff09; 目录 一、序 二、态度问题 三、问题点 3.1 项目过程管理的问题 3.2 配置管理的问题 …...

连新手小白都知道的电子画册一键生成器,你还不知道吗?

相信大家平时见得比较多的是纸质画册&#xff0c;而对于电子画册大家又了解多少呢&#xff1f;电子画册近年来倍受众多企业青睐&#xff0c;制作一本好的电子画册能够让企业在市场竞争中脱颖而出&#xff0c;给人以深刻印象。如何制作呢&#xff1f; 其实很简单&#xff0c;关…...

JAVAEE初阶 操作系统

操作系统的相关知识 一.操作系统的定位二.操作系统的作用三.什么是进程/任务1.进程在系统中如何操作和管理 四.PCB中的核心属性1.pid2.内存指针3.文件描述符表 五.CPU1.cpu的特性:分时复发 六.PCB中进行调度的属性1.状态2.优先级3.记账信息 一.操作系统的定位 二.操作系统的作用…...

第四代智能井盖传感器:万宾科技智能井盖位移监测方式一览

现在城市化水平不断提高&#xff0c;每个城市的井盖遍布在城市的街道上&#xff0c;是否能够实现常态化和系统化的管理&#xff0c;反映了一个城市治理现代化水平。而且近些年来住建部曾多次要求全国各个城市加强相关的井盖管理工作&#xff0c;作为基础设施重要的一个组成部分…...

了解JS中的混个对象“类”

类是面向对象的设计模式&#xff0c;它包括实例化、继承和多态 1、理论 面向对象变成强调的是数据和操作的行为本质上是相互关联的&#xff0c;因此好的设计就是把数据以及和他相关的行为打包&#xff08;封装&#xff09;起来&#xff0c;我们也叫他数据结构。 类的一个核心…...

在Sprinng Boot中使用Redis充当缓存

关于我们使用EhCache可以适应很多的应用场景了&#xff0c;但是因为EhCache是进程内的缓存框架&#xff0c;在集群模式下&#xff0c;我们在我们的应用服务器或者云服务器之间的缓存都是独立的。故而在不同的服务器之间的进程会存在缓存不一致的情况&#xff0c;就算我们的EhCa…...

【网络】TCP协议的相关实验

TCP协议的相关实验 一、理解listen的第二个参数1、实验现象2、TCP 半连接队列和全连接队列3、关于listen的第二个参数的一些问题4、SYN洪水Ⅰ、什么是SYN洪水攻击Ⅱ、如何解决SYN洪水攻击&#xff1f; 二、使用Wireshark分析TCP通信流程 一、理解listen的第二个参数 在编写TCP…...

微服务测试怎么做

开发团队越来越多地选择微服务架构而不是单体结构&#xff0c;以提高应用程序的敏捷性、可扩展性和可维护性。随着决定切换到模块化软件架构——其中每个服务都是一个独立的单元&#xff0c;具有自己的逻辑和数据库&#xff0c;通过 API 与其他单元通信——需要新的测试策略和新…...

第9章 K8s进阶篇-持久化存储入门

9.1 k8s存储Volumes介绍 Container&#xff08;容器&#xff09;中的磁盘文件是短暂的&#xff0c;当容器崩溃时&#xff0c;kubelet会重新启动容器&#xff0c;但最初的文件将丢失&#xff0c;Container会以最干净的状态启动。另外&#xff0c;当一个Pod运行多个Container时&…...

MathType2024最新word公式编辑器

使用word进行论文编写时&#xff0c;常需要使用公式编辑器&#xff0c;但有些word中并没有公式编辑器&#xff0c;这时应该怎么办呢&#xff1f;本文将围绕word里没有公式编辑器怎么办&#xff0c;word中的公式编辑器怎么用的内容进行介绍。 一、word里没有公式编辑器怎么办 …...

英语语法 - 主语从句

[ 主语从句 ] 没有时态要求 | 三单 1. 从属连词 that 引导的主语从句 | 不做句子成分 | 没有意义 That a monster attacked a ship last week shocked the world. That I bought a house in Beijing shocks many people. That Oscar is rich makes us upset. That he didnt wa…...

千梦网创:实现自动化“挂机躺盈”的三种方法

在互联网众多行业中&#xff0c;有很多人一直在寻找所谓的“挂机躺盈”的项目&#xff0c;在理财领域这种收入被称为“被动收入”。 天上不会掉馅饼这是一句讲烂掉的话了&#xff0c;躺在家里吃白食等着钱进账是一件不可能的事情。 然而如果你看到身边有“被动收入”的例子&a…...

微信小程序页面传递参数方法

说明 页面跳转方法有很多中&#xff0c;但经常会通过一个页面传递参数给另一个页面&#xff0c;非常的常见。但数据量大的时候&#xff0c;通常用字符串传递&#xff0c;但会显得过于臃肿&#xff0c;下面介绍页面传递参数的各种方式。 一、页面跳转链接携带参数 例如&#xf…...

出行类app如何提升广告变现收益?

出行类APP已经成为越来越多人们出行的首选&#xff0c;出行类app在变现方式上存在以下痛点&#xff1a;APP功能单一、使用场景单一&#xff1b;用户使用时间集中&#xff0c;粘性低...这些痛点使得开发者获取收益的提升面临极大的挑战。 https://www.shenshiads.com 如何让出…...

Linux日志高效搜索:从基础grep到journalctl实战技巧

1. Linux日志搜索&#xff1a;运维工程师的必备技能 每次服务器出现异常&#xff0c;第一反应是什么&#xff1f;没错&#xff0c;就是查日志。作为在Linux系统摸爬滚打多年的老运维&#xff0c;我见过太多新手面对海量日志时的手足无措。其实日志排查就像破案&#xff0c;关键…...

数据结构与算法学习笔记

java一.数据结构简介1. 为什么要有数据结构&#xff1f;数据太多、太乱 → 无法高效处理 → 必须结构化2. 数据结构的两大分类逻辑结构&#xff1a;数据之间的关系&#xff08;怎么理解&#xff09;物理结构&#xff1a;内存中的存储方式&#xff08;怎么实现&#xff09;3. 逻…...

如何查看浏览器中当前存储的 Cookie?

如何查看浏览器中的 Cookie&#xff1f;为什么有些 Cookie 看不到&#xff1f;1. 引言&#xff1a;快递单号与隐私信封2. Cookie 是什么&#xff1f;&#xff08;小白必备&#xff09;3. 核心问题&#xff1a;为什么有些 Cookie“看不到”&#xff1f;4. 如何查看 Cookie&#…...

2025届毕业生推荐的十大降重复率神器横评

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 眼下&#xff0c;人工智能生成内容愈发普遍&#xff0c;各类AI检测工具便跟着出现了&#xf…...

从零构建:基于OpenCV与人体姿态分析的跌倒检测实战(附完整源码)

1. 为什么我们需要跌倒检测系统 想象一下家里的老人独自在客厅活动时突然摔倒的场景。这种意外在现实生活中并不罕见&#xff0c;尤其是对于行动不便的老年人群体。传统的解决方案往往依赖于佩戴式设备或紧急呼叫按钮&#xff0c;但这些方法要么需要用户主动操作&#xff0c;要…...

comsol燃料电池堆冷却:模型对聚合物电解质膜 (PEM) 燃料电池堆的热管理进行建模 对电...

comsol燃料电池堆冷却&#xff1a;模型对聚合物电解质膜 (PEM) 燃料电池堆的热管理进行建模 对电池堆的所有电池单元来说&#xff0c;以相似的温度曲线进行操作非常重要&#xff0c;因为非均匀的温度分布可能会导致非均匀的水蒸气冷凝&#xff0c;以及电池单元之间出现较大的性…...

Subtitle Edit:实现专业级字幕制作的7大创新方法指南

Subtitle Edit&#xff1a;实现专业级字幕制作的7大创新方法指南 【免费下载链接】subtitleedit the subtitle editor :) 项目地址: https://gitcode.com/gh_mirrors/su/subtitleedit 在视频内容创作与传播领域&#xff0c;字幕不仅是辅助理解的工具&#xff0c;更是提升…...

校园网环境下树莓派与Windows直连SSH的实战指南

1. 为什么需要网线直连树莓派&#xff1f; 在校园网环境下使用树莓派时&#xff0c;很多同学都会遇到这样的困扰&#xff1a;宿舍里没有路由器&#xff0c;校园WiFi又需要复杂的认证&#xff0c;根本无法让树莓派联网。这时候&#xff0c;一根普通的网线就能解决大问题。 我第一…...

数据库自动化指标采集与智能评分系统实践与构想

在数据库运维中&#xff0c;定期巡检是保障系统稳定性的基石。作者结合 MySQL 的运行机制&#xff0c;使用 Python 自主开发了一套数据库巡检脚本。本文将演示如何通过该脚本自动化采集 MySQL 的关键性能指标、生成可视化 HTML 报告&#xff0c;并引入综合评分机制评估数据库健…...

自动化智能体生成+外接MCP,我用 ModelEngine Nexent 5分钟手搓了一个小红书爆款收割机

前言&#xff1a;别让“工作流”困住了你的想象力 在 AI Agent 爆发的这一年&#xff0c;作为开发者&#xff0c;我们采用过“工作流&#xff08;Workflow&#xff09;”开发&#xff0c;提示词开发。 最近体验了 ModelEngine Nexent&#xff0c;它打出的 Slogan 是 “Your n…...