12.java程序员必知必会类库之HTML解析库

news2024/9/22 17:28:38

前言

HTML是开发经常遇见的一种报文格式。但是我们日常中,更多是用它来渲染数据。利用他的很多各种标签,格式化我们的数据。一般前端接触的比较多。

但是,随着爬虫技术在互联网上越来越流行,如何处理我们爬到的HTML。。。我们当然可以针对性的代码处理每个HTML,但是每个网站的每个HTML格式,样式都可能会有比较大的差异。市场上急需要一个类库,可以将html中的数据,正常解析,抽取出来。解析HTML的框架组件,受到大家的欢迎追捧。

本节,我就java如何实现HTML解析,做简单介绍

1 JSoup

1.1 介绍

官网英文翻译如下:
jsoup 是一个处理真实世界HTML的java类库。提供了方便的api用于抽取和操作数据,使用最好的HTML5DOM方法和CSS选择器。JSoup实现了 WHATWG 这家公司的h5规范,像浏览器一样,解析HTML到同一个DOM对象。

  1. 支持从文件,URL,或者字符串中获取解析HTML
  2. dom遍历或者CSS选择器发现和抽取数据
  3. 操作HTML元素,属性和内容
  4. 根据安全列表清除用户提交的内容,以防止XSS攻击
  5. 输出整洁的HTML
  6. jsoup的设计目的是处理各种各样的HTML,jsoup将创建一个合理的解析树。

1.2 pom坐标引入

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.10.2</version>
</dependency>

1.3 使用

1.3.1 加载文档的三种方式

只要解析的不是空字符串,就能返回一个结构合理的文档,其中包含(至少) 一个head和一个body元素。

一旦拥有了一个Document,你就可以使用Document中适当的方法或它父类 Element和Node中的方法来取得相关数据。

1.3.1.1 从字符串加载文档

@Test
public void testHtml1() {
    String html = "<html><head><title>First parse</title></head>"
            + "<body><p>Parsed HTML into a doc.</p></body></html>";
    Document doc = Jsoup.parse(html);
    System.out.println(doc);
}

1.3.1.2 从文件中加载文档

@Test
public void testHtml2() throws Exception {
    Document doc = Jsoup.parse(new File("E:\\weixinData\\WeChat Files\\wxid_gv8xbkloz0wc22\\FileStorage\\File\\2023-03\\test\\src\\main\\resources\\html\\test1.html"), "utf-8");
    System.out.println(doc);
}

1.3.1.3 从URL中加载文档

@Test
public void testHtml3() throws Exception {
    Document doc = Jsoup.connect("https://blog.csdn.net/wlyang666")
    		//可以在请求头添加cookie
            .cookie("token","232893asfasddfasfdas")
            //设置爬取超时时间
            .timeout(10000)
            //get请求
            .get();
    System.out.println(doc);
}

1.3.1.4 解析一个body片段

/**
 * @Description:解析body片段
 * @Author: wanlong
 * @Date: 2023/4/26 14:43
 * @return void
 **/
@Test
public void testParsePart() {
    String html = "<table><div><p>Lorem ipsum.</p>";
    Document doc = Jsoup.parseBodyFragment(html);
    Element body = doc.body();
    System.out.println(doc);
    System.out.println("=============");
    System.out.println(body);
}

使用正常的 Jsoup.parse(String html) 方法,通常也可以得到相同的结果,但是明确将用户输入作为 body片段处理,以确保用户所提供的任何糟糕的HTML都将被解析成body元素。

1.3.2 dom主要api介绍

1.3.2.1 获取元素

getElementById(String id);
getElementsByTag(String tag);
getElementsByClass(String className);
getElementsByAttribute(String key);

siblingElements();
firstElementSibling();
lastElementSibling();
nextElementSibling();
previousElementSibling();

siblingElements();
firstElementSibling();
lastElementSibling();
nextElementSibling();
previousElementSibling();

parent();
children();
child(int index);

1.3.2.2 元素数据和属性

//获取属性
attr(String key);
//设置属性
attr(String key, String value);
//获取所有属性
attributes();
//获取元素ID
id();
//获取元素类名
className(); 
//获取元素所有类名
classNames();
//获取元素文本内容
text();
//设置元素文本内容
text(String value);
//获取元素内HTML
html();
//获取元素外HTML内容
outerHtml();
//获取元素数据内容(例如:script和style标签)
data();
//获取元素tag  和 tag名字
tag();
tagName();

1.4 测试案例

1.4.1 需求:

需要获得CSDN排行榜作者榜每个作者的用户名和名次,这里只简单演示排名如何用解析HTML的方式爬取,方式不一定合理,甚至也能通过直接api接口的方式获取数据。只是为了演示解析HTML。

1.4.2 步骤

  1. 调接口获取前100个用户的用户名
@Test
public void test(){
    Map<String,String> resultMap=new LinkedHashMap<>();
    for (int i = 1; i <5 ; i++) {
        String url = String.format("https://blog.csdn.net/phoenix/web/v2/rank?page=%s&pageSize=25&rankType=total_author", "" + i);
        String data = HttpUtil.get(url);
        JSONObject jsonData = JSONObject.parseObject(data);
        JSONArray list = jsonData.getJSONObject("data").getJSONArray("list");
        for (Object o : list) {
            JSONObject json=(JSONObject)o;
            resultMap.put(json.getString("userName"),json.getString("currentRank"));
        }
    }
    System.out.println(JSONObject.toJSONString(resultMap));
}

在这里插入图片描述
2. 逐个到这100个用户首页,爬取用户首页HTML,解析HTML,获取排名

@Test
public void testHtml3() throws Exception {
   //这里正常维护的是前100个用户的用户名和接口获取的排名信息,这里考虑到用户隐私不展示,用我的账号做测试
   String str="{\"wlyang666\":\"22\"}";
   Map<String, String> resultMap = new LinkedHashMap<>();
   //1.读取博客总榜
   JSONObject json = JSONObject.parseObject(str);
   for (Map.Entry<String, Object> stringObjectEntry : json.entrySet()) {
       String username = stringObjectEntry.getKey();
       String url = String.format("https://blog.csdn.net/%s", username);
       //2.遍历每个作者,读取每个作者排名
       Document doc = Jsoup.connect(url)
               .cookie("token", "232893asfasddfasfdas")
               .timeout(10000)
               .get();
       //解析文档
       Elements paimingDiv = doc.getElementsMatchingOwnText("排名");
       for (Element element : paimingDiv) {
           try {
               String paiming = element.firstElementSibling().text();
               resultMap.put(username, paiming);
           } catch (Exception e) {
               System.out.println("有异常" + element);
               e.printStackTrace();
           }
       }
   }
   System.out.println(JSONObject.toJSONString(resultMap));
}

1.4.3 运行结果

{“wlyang666”:“17,152”}

1.5 注意事项:

  1. 解析HTML可传参数 baseUri 是用来将相对 URL 转成绝对URL,并指定从哪个网站获取文档。
  2. 解析html有各种可能失败的场景,包括上面的案例,在真实测试的时候,也有个别客户解析失败,这种建议先捕获异常,后期考虑看是否做兼容处理,还是个别数据不重要直接丢弃
  3. 爬取网页过程,可能需要校验登录信息等,此时可以在请求头封装token,cokkie等信息

参考文档:

jsoup官网

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

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

相关文章

[DASCTF Apr.2023 X SU战队2023开局之战] crypto复现

感觉突然啥都不会了,后来拿到官方WP,也没整明白,这官方的WP没有代码只讲了些道理,复现一下也不容易。 1&#xff0c;easySign 这是个自制的签名题。 from secret import r, t from Crypto.Util.number import *flag bxxx flag bytes_to_long(flag) e 0x10001def gen_keys…

53.网页设计规则#2_配色

选择正确的颜色 让主色调与你的网站个性相匹配&#xff1a;颜色传递意义 a. 红色吸引了很多人的注意&#xff0c;象征着权力、激情和兴奋。 b. 橙色不那么具有攻击性&#xff0c;并传达出幸福、愉快和创造性。 c. 黄色意味着快乐、光明和智慧 d. 绿色代表和谐、自然、成长和健康…

数学建模第六天:数学建模算法篇之插值及MATLAB实现

目录 一、前言 1、引例 2、插值与拟合模型 二、插值 1、插值相关定义 2、拉格朗日插值 3、分段线性插值 4、matlab实现 5、二维插值及matlab实现 一、前言 1、引例 伍老师最近苦不堪言&#xff0c;最近胡吃海喝&#xff0c;管不住嘴&#xff0c;感觉自己最近张胖了&am…

【数据去重】海量数据实时去重方案

文章目录 Prologue布隆过滤器去重什么是布隆过滤器实现的核心思想怎么理解 内嵌RocksDB状态后端去重引入外部K-V存储去重 Prologue 数据去重&#xff08;data deduplication&#xff09;是我们大数据攻城狮司空见惯的问题了。除了统计UV等传统用法之外&#xff0c;去重的意义更…

信号完整性分析基础知识之传输线和反射(四):不连续点和端接

每当信号遇到阻抗变化&#xff0c;就会出现反射现象&#xff0c;反射对信号质量影响很大。信号完整性工作最重要的部分之一就是预测不连续点对信号的影响&#xff0c;以及设计工程可接受的备选方案。 尽管电路板在设计上是可控阻抗互连&#xff0c;但是信号在以下结构中仍然会遇…

如何选择最佳的实时聊天软件

在客户服务和支持领域&#xff0c;实时聊天正在改变游戏规则已不是什么秘密。从推动销售到提升客户体验和提高保留率&#xff0c;实时聊天已成为与客户互动和支持的一种全新的方式。客户和支持专业人员都注意到了这一点。 研究发现&#xff0c;高达41%的消费者更喜欢实时聊天&…

李宏毅 深度学习

目录 深度学习与自然语言处理 | 斯坦福CS224n 课程带学与全套笔记解读&#xff08;NLP通关指南完结&#xff09;pytorch快速入门csdn快速入门OS包PIL包Opencv包Dataset类Tensorboard的使用torchvision.transforms 的使用torchvision中数据集的使用DataLoader的使用(torch.util…

【C++】:想知道如何实现互译字典吗?来看二叉搜索树

二叉搜索树好文&#xff01; 文章目录 前言一、实现搜索二叉树二、二叉搜索树的应用 1.K模型2.KV模型总结 前言 二叉搜索树概念 &#xff1a; 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树 &#xff0c;或者是具有以下性质的二叉树 : 若它的左子树不为空&#xff0…

Orcale中OCILogon和OCIServerAttach登录方式的区别分析

参考文档《Oracle Call Interface Programmers Guide》 在Orcale和DM数据库提供的API中&#xff0c;通过OCI方式接口连接数据库的方法有多个&#xff0c;这里只讨论OCILogon和OCIServerAttach的比较。 1、官方描述 根据文档里的描述&#xff1a; OCILogon():This function is…

DJ4-5 路由和选路

目录 一、路由与转发的相互作用 二、路由的基本概念 1. 默认路由器 2. 路由算法 三、网络的抽象模型 1. 节点图 2. 费用 Cost 四、路由算法分类 1. 静态路由算法 2. 动态路由算法 3. 全局路由算法 4. 分布式路由算法 一、路由与转发的相互作用 二、路由的基本概念 …

美团赴抖音之“约”:让本地生活补贴大战来得更猛烈些?

面对抖音在本地生活领域的强势挑战&#xff0c;美团似乎准备好了正面迎战。 近期&#xff0c;美团动作频频。最开始&#xff0c;美团在美团App美食页面下的“特价团购”打出“限时补贴&#xff0c;全网低价”的口号。对此&#xff0c;一位行业人士分析称&#xff0c;“之前美团…

java commons-io 工具类的使用

commons-io是第三方程序员编写的工具类&#xff0c;并不是java本身带的方法。是在java提供的工具类基础上&#xff0c;开发的工具类。简化了代码的用法&#xff0c;可以提升开发效率。 用法 1.下载jar包 2.在程序中新建lib目录&#xff0c;把jar包放进去 3.在jar包上右键&…

learn_C_deep_6 (布尔类型、布尔与“零值“、浮点型与“零值“、指针与“零值“的比较)

目录 语句和表达式的概念 if语句的多种语法结构 注释的便捷方法&#xff08;环境vs&#xff09; if语句执行的过程 逻辑与&& 逻辑或|| 运算关系的顺序 else的匹配原则 C语言有没有布尔类型 C99标准 sizeof(bool)的值为多少&#xff1f; _Bool原码 BOOL…

音视频八股文(6)-- ffmpeg大体介绍和内存模型

播放器框架 常用音视频术语 • 容器&#xff0f;文件&#xff08;Conainer/File&#xff09;&#xff1a;即特定格式的多媒体文件&#xff0c; 比如mp4、flv、mkv等。 • 媒体流&#xff08;Stream&#xff09;&#xff1a;表示时间轴上的一段连续数据&#xff0c;如一 段声音…

dubbogo如何实现路由规则功能

dubbo-go中如何实现路由规则功能 路由规则&#xff08; routing rule &#xff09;是为了改变网络流量所经过的途径而修改路由信息的技术&#xff0c;主要通过改变路由属性&#xff08;包括可达性&#xff09;来实现。在发起一次 RPC 调用前起到过滤目标服务器地址的作用&…

Node第三方包 【node-xlsx】

文章目录 &#x1f31f;前言&#x1f31f;node-xlsx&#x1f31f;安装&#x1f31f;导出xlsx文件&#x1f31f;解析xlsx文件&#x1f31f;另外&#xff1a;其他支持读写Excel的Node.js模块有&#xff1a;&#x1f31f;直接导出excel文件 &#x1f31f;写在最后 &#x1f31f;前…

麒麟信安联合主办 | openEuler Developer Day 2023召开 openEuler全场景走向深入

【中国&#xff0c;上海&#xff0c;2023年4月21日】openEuler Developer Day 2023于4月20-21日在线上和线下同步举办。本次大会由开放原子开源基金会、中国软件行业协会、openEuler社区、边缘计算产业联盟共同主办&#xff0c;以“万涓汇流&#xff0c;奔涌向前”为主题&#…

【FTP工具】- Win10下免费的FTP服务器搭建 - FileZilla 的下载、安装、使用

目录 一、概述二、下载、安装2.1 下载2.2 安装 三、FileZilla服务器的使用3.1 连接服务器3.2 配置用户权限 四、在windows访问该Ftp服务器4.1 查看Ftp服务器IP4.2 访问Ftp服务器 一、概述 FileZilla服务器是一个免费的开源FTP和FTPS服务器&#xff0c;是根据GNU通用公共许可证条…

HTB靶机03-Shocker-WP

Shocker scan 2023-03-30 23:22 ┌──(xavier㉿xavier)-[~/Desktop/Inbox] └─$ sudo nmap -sSV -T4 -F 10.10.10.56 Starting Nmap 7.91 ( https://nmap.org ) at 2023-03-30 23:22 HKT Nmap scan report for 10.10.10.56 Host is up (0.40s latency). Not shown: 99 clos…

QT-day(2)-(常用类、信号与槽.....)

题目&#xff1a;编写一个登录功能的界面&#xff0c;在登录框项目中&#xff0c;将登陆按钮发射的tclicked信号&#xff0c;连接到自定义的槽函数中&#xff0c;在槽函数中&#xff0c;判断u界面输入的用户名是否为"admin ,密码是否为"123456如果验证成功&#xff0…