从 Ballance 地图管理站(永硕网盘)拉取地图信息。以 JavaScript 实现,配有演示用 HTML 页面。
永硕网盘存储系统的结构如下:
- 目录1
- 文件1.1
- 文件1.2
- 目录2
- 文件2.1
- ...
- ...
永硕本身使用网盘用户名获取目录列表。目录本身存在数字编号;当用户点击目录时,使用目录的数字编号获取文件列表及属性等。
此外,Ballance 地图管理站对于文件的备注信息上存在额外结构:文件的备注信息总是以 作者 | 难度 | 其他备注 格式呈现,但难度和其他备注信息不一定存在。
创建一个新的 MapDataFetcher 对象:
let fetcher = new MapDataFetcher();
使用 getGroupIndexes(样式: String) 异步方法方法获取。关键词使用正则表达式,用于过滤出来满足样式的目录列表。
第一次获取目录列表后会将数据作为缓存储存在对象中。强制刷新请使用 refresh()。
被解析为满足对应样式的目录的对象数组的 Promise 对象:
[
{
id: 目录的数字编号
name: 目录名
notes: 备注信息
},
...
]
加载失败或没有满足样式的目录时返回空数组。
fetcher.getGroupIndexes("Ballance自制地图") 返回(此处仅截取其中一部分):
[
{
id: "1767721",
name: "Ballance自制地图【HOT】",
notes: "热评地图分区(截至2020年6月)"
},
{
id: "1767719",
name: "Ballance自制地图【CLASSIC】",
notes: "经典地图分区(2015年及以前的经典地图)"
},
...
]
使用 getMapList(目录编号: String) 异步方法获取。目录编号对应前文的 id。
第一次获取文件列表后会将数据作为缓存储存在对象中。强制刷新请使用 refresh()。
被解析为对应目录的地图文件内容的对象数组的 Promise 对象:
[
{
author: 作者,
difficulty: 难度,
name: 地图名称,
notes: 其他备注信息,
size: 文件大小,
uploadTime: 文件上传时间,
url: 下载链接
},
...
]
难度数据 difficulty 使用数字格式表示,不存在时为 -1。
注意:永硕的下载链接是会定期改变的,因此无法长期储存。
fetcher.getMapList("1315478") 返回(此处仅截取其中一部分):
[
{
author: "BallanceBug",
difficulty: -1,
name: "210522图.nmo",
notes: "",
size: "1.8MB",
uploadTime: "2021/5/30 12:48:42",
url: "http://ys-O.ysepan.com/342124442/524199091/n475I5447FKQ8KT8RIkL2a/210522图.nmo"
},
{
author: "Ballexer",
difficulty: -1,
name: "圈套.zip",
notes: "2021-04-05更新版,规则同下",
size: "12.3MB",
uploadTime: "2021/5/22 23:47:52",
url: "http://ys-N.ysepan.com/342124433/524187718/U6VHgNp863H6574GMP5T8e/圈套.zip"
},
...
]
第一次获取目录列表或文件列表后,数据会作为缓存储存在对象中,之后获取时返回的是缓存数据。使用 refresh() 方法可以清除这些缓存;再次加载时它们会被重新获取。
永硕使用 AJAX 的方式加载目录和文件列表,加载时的 HTTP 请求需要含有 Referer 请求头,否则会提示错误。加载出的内容是永硕已经生成好的格式化的 HTML 及一些额外的脚本信息,所以需要将额外脚本过滤掉后解析 HTML。
在 JS 内解析永硕的格式化 HTML 有以下二种方式:
- 使用 HTML 相关的解析器。
- 暴力正则表达式。
乍一看前者似乎必定是最佳方式,但其实不然:
- 永硕本身没有真正意义上的稳定的 RESTful API,所获取到的 HTML 格式混乱,甚至还存在语法错误,相当不便查找与解析。
- 永硕的样式时常变化,若以本地软件形式提供给用户使用,只要格式发生变化,就会无法解析。为了解决,需要经常性在线自动获取解析规则。如果使用 HTML 解析器,联网获取解析代码并 eval 执行显然存在安全隐患;而正则表达式本身为字符串,可以避免上述问题。
- 不同语言下 HTML 解析器用法和格式不同,不便移植,但正则表达式是一致的。
本项目使用正则表达式解析。