Spring Boot集成jsoup实现html解析
1.什么是jsoup
jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据,可操作 HTML 元素、属性、文本。
JSoup 功能
jsoup 实现 WHATWG HTML5 规范,并将 HTML 解析为与现代浏览器相同的 DOM。
- 从 URL,文件或字符串中提取并解析 HTML。
- 查找和提取数据,使用 DOM 遍历或 CSS 选择器。
- 操纵 HTML 元素,属性和文本。
- 根据安全的白名单清理用户提交的内容,以防止 XSS 攻击。
- 输出整洁的 HTML。
JSoup 主要类
大多数情况下,下面给出 3
个类是我们需要重点了解的。
Jsoup 类
Jsoup 类是任何 Jsoup 程序的入口点,并将提供从各种来源加载和解析 HTML 文档的方法。 Jsoup 类的一些重要方法如下:
方法 | 描述 |
---|---|
static Connection connect(String url) | 创建并返回 URL 的连接。 |
static Document parse(File in, String charsetName) | 将指定的字符集文件解析成文档。 |
static Document parse(String html) | 将给定的 html 代码解析成文档。 |
static String clean(String bodyHtml, Whitelist whitelist) | 从输入 HTML 返回安全的 HTML,通过解析输入 HTML 并通过允许的标签和属性的白名单进行过滤。 |
Jsoup 类的其他重要方法可以参见 - Jsoup: jsoup HTML Parser Documentation
Document 类
该类表示通过 Jsoup 库加载 HTML 文档。可以使用此类执行适用于整个 HTML 文档的操作。 Element 类的重要方法可以参见 - Document: jsoup HTML Parser Documentation 。
Element 类
HTML 元素是由标签名称,属性和子节点组成。 使用 Element 类,您可以提取数据,遍历节点和操作 HTML。 Element 类的重要方法可参见 - Element: jsoup HTML Parser Documentation 。
2.代码工程
实验目的
实现解析liuhaihua.cn首页list
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springboot-demo</artifactId><groupId>com.et</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>jsoup</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.12.1</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency></dependencies>
</project>
controller
package com.et.jsoup;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;@RestController
public class HelloWorldController {@RequestMapping("/hello")public Map<String, Object> showHelloWorld(){Map<String, Object> map = new HashMap<>();map =JsoupUtil.parseHtml("http://www.liuhaihua.cn/");map.put("msg", "HelloWorld");return map;}
}
工具类
package com.et.jsoup;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;/*** @author liuhaihua* @version 1.0* @ClassName JsoupUtil* @Description todo* @date 2024/06/24/ 9:16*/public class JsoupUtil {public static Map<String ,Object> parseHtml(String url){Map<String,Object> map = new HashMap<>();//1.生成httpclient,相当于该打开一个浏览器CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = null;//2.创建get请求,相当于在浏览器地址栏输入 网址HttpGet request = new HttpGet(url);//设置请求头,将爬虫伪装成浏览器request.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");
// HttpHost proxy = new HttpHost("60.13.42.232", 9999);
// RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
// request.setConfig(config);try {//3.执行get请求,相当于在输入地址栏后敲回车键response = httpClient.execute(request);//4.判断响应状态为200,进行处理if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//5.获取响应内容HttpEntity httpEntity = response.getEntity();String html = EntityUtils.toString(httpEntity, "utf-8");System.out.println(html);/*** 下面是Jsoup展现自我的平台*///6.Jsoup解析htmlDocument document = Jsoup.parse(html);//像js一样,通过标签获取titleSystem.out.println(document.getElementsByTag("title").first());Elements blogmain = document.getElementsByClass("col-sm-8 blog-main");//像js一样,通过class 获取列表下的所有博客Elements postItems = blogmain.first().getElementsByClass("fade-in");//循环处理每篇博客List<Map> list = new ArrayList<>();for (Element postItem : postItems) {Map<String,Object> row = new HashMap<>();//像jquery选择器一样,获取文章标题元素Elements titleEle = postItem.select(".entry-title a");System.out.println("文章标题:" + titleEle.text());;row.put("title",titleEle.text());System.out.println("文章地址:" + titleEle.attr("href"));row.put("href",titleEle.attr("href"));//像jquery选择器一样,获取文章作者元素Elements footEle = postItem.select(".archive-content");System.out.println("文章概要:" + footEle.text());;row.put("summary",footEle.text());Elements view = postItem.select(".views");System.out.println( view.text());row.put("views",view.text());System.out.println("*********************************");list.add(row);}map.put("data",list);} else {//如果返回状态不是200,比如404(页面不存在)等,根据情况做处理,这里略System.out.println("返回状态不是200");System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));}} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {//6.关闭HttpClientUtils.closeQuietly(response);HttpClientUtils.closeQuietly(httpClient);}return map;}public static void main(String[] args) {parseHtml("http://www.liuhaihua.cn/");}}
DemoApplication.java
package com.et.jsoup;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}
以上只是一些关键代码,所有代码请参见下面代码仓库
代码仓库
- GitHub - Harries/springboot-demo: a simple springboot demo with some components for example: redis,solr,rockmq and so on.
3.测试
- 启动spring boot应用
- 访问http://127.0.0.1:8088/hello,返回解析结果
4.引用
- 官网:jsoup: Java HTML parser, built for HTML editing, cleaning, scraping, and XSS safety
- GitHub:GitHub - jhy/jsoup: jsoup: the Java HTML parser, built for HTML editing, cleaning, scraping, and XSS safety.
- Spring Boot集成jsoup实现html解析 | Harries Blog™
相关文章:
Spring Boot集成jsoup实现html解析
1.什么是jsoup jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据,可操作 HTML 元素、属性、文本。 JSo…...
[240629] 阿里云揭秘其数据中心设计和自研网络,用于大语言模型训练 | Jina AI 发布最新的神经网络重排序模型
目录 阿里云揭秘其数据中心设计和自研网络,用于大语言模型训练Jina AI 发布最新的神经网络重排序模型 阿里云揭秘其数据中心设计和自研网络,用于大语言模型训练 阿里云近日公布了其专为大型语言模型 (LLM) 训练流量而设计的基于以太网的网络设计&#x…...

【Docker0】网络更改
目录 1. 停止docker服务 2. 关闭docker默认桥接网络接口 3. 从系统删除docker0接口 4. 创建一个名为bridge0的新接口 5. 添加ip地址和子网掩码 6. 启用bridge0接口 7. (如果没起来就执行该句) 8. 查看ip 1. 停止docker服务 sudo service docker…...

IDEA中导入Maven项目
IDEA中导入Maven项目 方式1:使用Maven面板,快速导入项目 打开IDEA,选择右侧Maven面板,点击 号,选中对应项目的pom.xml文件,双击即可 说明:如果没有Maven面板,选择 View > Appe…...
px、em、rem、rpx 作用和用法详解
px px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。 PX特点 IE无法调整那些使用px作为单位的字体大小; 国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位; Firefox能够调整px和emÿ…...
Linux 常用命令 - dd 【复制及转换文件内容】
简介 dd 命令源自于磁盘复制(disk dump)的缩写,是 Linux 和 Unix 系统中用于转换和复制文件的一个强大工具。它可以在复制过程中进行格式转换,支持不同的块大小,能够直接对硬盘设备进行操作,非常适合进行备…...

全网唯一免费无水印AI视频工具!
最近Morph Studio开始免费公测!支持高清画质,可以上传语音,同步口型,最重要的是生成的视频没有水印! Morph Studio国内就可以访问,可以使用国内邮箱注册(我用的163邮箱),…...

kafka(四)消息类型
一、同步消息 1、生产者 同步发送的意思就是,一条消息发送之后,会阻塞当前线程,直至返回 ack。 由于 send 方法返回的是一个 Future 对象,根据 Futrue 对象的特点,我们也可以实现同 步发送的效果,只需在调…...

Emacs之显示blame插件:blamer、git-messenger(一百四十四)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...

【10分钟速通webpack,全流程打包,编译,发包,全干货,附代码 】
需求 后端有个nodejs 基础库,用typescript编写,需要发包到代码仓库上,被其它业务引入。这其中就涉及了: 编译, 打包,发包。 工作流速览 前提依赖 webpack主体 npm install --save-dev webpack webpack…...
设计模式深入解析与实例应用
目录 工厂模式1.简单工厂模式2.工厂方法模式3.抽象工厂模式 策略模式责任链模式概述模板方法模式概述单例模式概述 工厂模式 工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳实践,旨在将对象的创建过程与使用过程分离,以提高代码的…...

服务器数据恢复—异常断电导致RAID6阵列中磁盘出现坏扇区的数据恢复案例
服务器存储数据恢复环境: 一台存储中有一组由12块SAS硬盘组建的RAID6磁盘阵列,划分为一个卷,分配给几台Vmware ESXI主机做共享存储。该卷中存放了大量Windows虚拟机,这些虚拟机系统盘是统一大小,数据盘大小不确定&…...

前端工程化08-新的包管理工具pnpm
1、历史原因解读 pnpm这个东西发布的时间是比较早的,但是在最近一两年的时候才开始流行,甚至是可以说非常的盛行,那么这个包到底是个什么东西的,那么我们先说下,原来的包管理工具到底有那些问题?比如说我们…...

章十九、JavaVUE —— 框架、指令、声明周期、Vue-cli、组件路由、Element
目录 一、 框架 ● vue.js 框架 ● 特点 ● Vue 安装 二、 第一个vue程序 ● 创建项目 编辑 ● 导入 vue.js ● 创建vue对象,设置属性,使用模版渲染到页面 介绍 — Vue.js (vuejs.org) 三、 vue指令 ● v-text ● v-html ● v-…...

正则表达式阅读理解
这段正则表达式可以匹配什么呢? 超级复杂的一段正则表达式。 ((max|min)\\s*\\([^\\)]*(,[^\\)]*)*\\)|[a-zA-Z][a-zA-Z0-9]*(_[a-zA-Z][a-zA-Z0-9]*)?(\\*||%)?|[0-9](\\.[0-9])?|\\([^\\)]*(,[^\\)]*)*\\))(\\s*[-*/%]\\s*([a-zA-Z][a-zA-Z0-9]*(_[a-zA-Z][…...
Apache Calcite Linq4j学习
Lin4j简介 Linq4j是Apache Calcite项目中的一个模块,它提供了类似于LINQ(Language-Integrated Query)的功能,用于在Java中进行数据查询和操作。Linq4j可以将逻辑查询转换为物理查询,支持对集合进行筛选、映射、分组等…...

FPGA SATA高速存储设计
今天来讲一篇如何在fpga上实现sata ip,然后利用sata ip实现读写sata 盘的目的,如果需要再速度和容量上增加,那么仅仅需要增加sata ip个数就能够实现增加sata盘,如果仅仅实现data的读写整体来说sata ip设计比较简单,下面…...
MySQL----为什么选择使用MySQL
在我们日常做项目的过程中,不论是个人还是企业,大多数会选择使用MySQL数据库作为后端数据库存储,它到底有什么优势,能够做到如此广为流传呢? 优点 稳定性:MySQL具有良好的稳定性和可靠性,能够保…...
01.音视频小白系统入门(新专栏)
目录 一、基础知识 二、音频 三、视频 四、流媒体服务器 五、收获 音视频技术在远程办公、在线教育、远程医疗等领域的应用广泛。 学习音视频技术有助于提升职业竞争力,满足市场需求。 掌握音视频基础知识对未来发展至关重要,基础不牢会导致后续学习…...

C++:enum枚举共用体union
enum枚举 C继承C的枚举用法 (1)典型枚举类型定义,枚举变量定义和使用 (2)枚举类型中的枚举值常量不能和其他外部常量名称冲突: 举例1宏定义,举例2另一个枚举 // 定义一个名为Color的枚举类型 enum Color {RED, // 红色,默认值…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...