Java使用Jsoup实现将浏览器书签HTML转换为JSON

 更新时间:2026年01月18日 08:59:19   作者:weixin_46244623  
这篇文章主要介绍了如何使用Jsoup和Fastjson2将浏览器导出的书签HTML文件解析为层级化的JSON结构,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以了解下

一、背景说明

浏览器(Chrome / Edge / Firefox)导出的书签文件,通常是 Netscape Bookmark HTML 格式
在实际开发中,我们可能会遇到以下需求:

  • 将浏览器书签导入到自己的系统
  • 对书签进行结构化存储(如数据库、JSON)
  • 做书签导航站、搜索、同步工具等

本文通过 Jsoup + Fastjson2,演示如何将书签 HTML 解析为层级 JSON 结构,并支持 递归子目录

二、书签 HTML 格式说明

浏览器导出的书签文件大致结构如下:

<DL>
  <DT><H3>文件夹</H3>
  <DL>
    <DT><A href="https://www.baidu.com/" rel="external nofollow" >百度</A>
    <DT><H3>子文件夹</H3>
    <DL>
      <DT><A href="https://map.baidu.com/" rel="external nofollow" >百度地图</A>
    </DL>
  </DL>
</DL>

关键点:

  • <H3>:表示一个文件夹
  • <A>:表示一个书签链接
  • <DL>:表示当前文件夹的内容
  • 文件夹与其内容是 H3 → 紧跟的 DL

三、技术选型

技术作用
Jsoup解析 HTML DOM
Fastjson2构建 JSON 数据
JUnit + SpringBootTest测试运行

四、完整示例代码

下面给出 完整可运行代码,包括导入、类定义和递归方法:

package com.nav.test;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)
public class Bookmark {

    @Test
    public void main() {
        // 模拟浏览器导出的书签 HTML 内容
        String bookmarkContent = "<!DOCTYPE NETSCAPE-Bookmark-file-1>\n" +
                "<!-- This is an automatically generated file. -->\n" +
                "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n" +
                "<TITLE>Bookmarks</TITLE>\n" +
                "<H1>Bookmarks</H1>\n" +
                "<DL><p>\n" +
                "    <DT><H3 ADD_DATE=\"1632971641\" LAST_MODIFIED=\"1689686797\" PERSONAL_TOOLBAR_FOLDER=\"true\">书签栏</H3>\n" +
                "    <DL><p>\n" +
                "        <DT><A HREF=\"https://www.baidu.com/\" ADD_DATE=\"1689686710\">百度一下,你就知道</A>\n" +
                "        <DT><H3 ADD_DATE=\"1689686747\" LAST_MODIFIED=\"1689686798\">子书签</H3>\n" +
                "        <DL><p>\n" +
                "            <DT><A HREF=\"https://map.baidu.com/\" ADD_DATE=\"1689686769\">百度地图</A>\n" +
                "        </DL><p>\n" +
                "    </DL><p>\n" +
                "</DL><p>";

        // 使用 Jsoup 解析 HTML
        Document doc = Jsoup.parse(bookmarkContent);

        // 找到书签栏(Chrome 的 PERSONAL_TOOLBAR_FOLDER)
        Element mainFolder = doc.select("h3[personal_toolbar_folder]").first();

        // 递归处理
        JSONObject result = processFolder(mainFolder);

        // 输出 JSON
        System.out.println(result.toJSONString());
    }

    /**
     * 递归处理文件夹
     *
     * @param folderElement 文件夹对应的 H3 元素
     * @return JSONObject 结构 {name, links, subFolders}
     */
    private static JSONObject processFolder(Element folderElement) {
        JSONObject folderJson = new JSONObject();

        // 文件夹名称
        folderJson.put("name", folderElement.text());

        // 当前文件夹对应的 <DL>
        Element dl = folderElement.nextElementSibling();

        // 当前目录下的链接
        JSONArray links = new JSONArray();
        for (Element a : dl.select("> dt > a")) {
            JSONObject linkJson = new JSONObject();
            linkJson.put("name", a.text());
            linkJson.put("url", a.attr("href"));
            links.add(linkJson);
        }
        folderJson.put("links", links);

        // 子文件夹
        JSONArray subFolders = new JSONArray();
        for (Element h3 : dl.select("> dt > h3")) {
            subFolders.add(processFolder(h3));
        }
        folderJson.put("subFolders", subFolders);

        return folderJson;
    }
}

五、输出 JSON 示例

运行上面的代码,控制台输出类似:

{
  "name": "书签栏",
  "links": [
    {
      "name": "百度一下,你就知道",
      "url": "https://www.baidu.com/"
    }
  ],
  "subFolders": [
    {
      "name": "子书签",
      "links": [
        {
          "name": "百度地图",
          "url": "https://map.baidu.com/"
        }
      ],
      "subFolders": []
    }
  ]
}

六、实现思路总结

  • H3 表示文件夹
  • H3 后面的 DL 是内容
  • 使用 nextElementSibling() 关联目录
  • 递归解析子文件夹
  • 通过 > dt > a> dt > h3 选择器分别获取当前目录的书签和子文件夹

到此这篇关于Java使用Jsoup实现将浏览器书签HTML转换为JSON的文章就介绍到这了,更多相关Java浏览器书签HTML转JSON内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringMVC实现多文件上传

    SpringMVC实现多文件上传

    这篇文章主要为大家详细介绍了SpringMVC实现多文件上传功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • java中运算符使用步骤(超详细!)

    java中运算符使用步骤(超详细!)

    Java中的运算符是编程语言中最基本的组成部分,对于数据的操作和处理起着至关重要的作用,这篇文章主要介绍了java中运算符使用步骤的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-11-11
  • Java多线程产生死锁的必要条件

    Java多线程产生死锁的必要条件

    今天小编就为大家分享一篇关于Java多线程产生死锁的必要条件,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Java中的延迟队列DelayQueue详细解析

    Java中的延迟队列DelayQueue详细解析

    这篇文章主要介绍了Java中的延迟队列DelayQueue详细解析,JDK自身支持延迟队列的数据结构,其实类:java.util.concurrent.DelayQueue,<BR>我们通过阅读源码的方式理解该延迟队列类的实现过程,需要的朋友可以参考下
    2023-12-12
  • Java来实现文本转图片需求示例

    Java来实现文本转图片需求示例

    本文主要介绍了Java来实现文本转图片需求示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-04-04
  • 浅析Spring Cloud Gateway中的令牌桶限流算法

    浅析Spring Cloud Gateway中的令牌桶限流算法

    这篇文章主要为大家浅析了Spring Cloud Gateway中的令牌桶限流算法原理,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • Struts2实现自定义拦截器的三种方式详解

    Struts2实现自定义拦截器的三种方式详解

    这篇文章主要介绍了Struts2实现自定义拦截器的三种方式详解,一些与系统逻辑相关的通用功能如权限的控制和用户登录控制等,需要通过自定义拦截器实现,本节将详细讲解如何自定义拦截器,需要的朋友可以参考下
    2023-07-07
  • java集合map取key使用示例 java遍历map

    java集合map取key使用示例 java遍历map

    这篇文章主要介绍了java集合map取key使用示例,需要的朋友可以参考下
    2014-02-02
  • SpringBoot中开启GZIP压缩的方式

    SpringBoot中开启GZIP压缩的方式

    这篇文章主要介绍了SpringBoot中开启GZIP压缩的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • Spring中@Qualifier注解的用法

    Spring中@Qualifier注解的用法

    但凡有点开发经验,多多少少可能都遇到过@Qualifier注解的使用场景,本文主要介绍了Spring中@Qualifier注解的用法,感兴趣的可以了解一下
    2023-11-11

最新评论