一、背景说明
浏览器(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内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论