首页龙虾技能列表 › Shanghai Library Seat Booking — 技能工具

Shanghai Library Seat Booking — 技能工具

v0.1.9

上海图书馆东馆三楼座位预约。支持浏览器自动化登录获取认证信息,以及基于API的座位预约(指定座位或系统自动分配)。适用于需要自动化预约图书馆座位的场景。

1· 132·0 当前·0 累计
by @jenslewie·MIT-0
下载技能包
License
MIT-0
最后更新
2026/3/20
安全扫描
VirusTotal
无害
查看报告
OpenClaw
安全
high confidence
这个技能看起来与其描述一致:用于上海图书馆座位预约,会在本地读写配置/认证文件并通过 Playwright 启动浏览器以获取令牌,未发现与功能不符的网络后门或多余权限请求。
评估建议
主要注意事项: - 这是一个本地运行的 Node.js 脚本,会在 ~/.config/shlibrary-seat-booking 下读取/写入认证文件(accessToken/sign/timestamp),只有在你提供读者证并登录后才会有有效凭证。不要把这些文件上传或分享给他人。 - 安装 Playwright 会通过 npx 下载 Chromium 二进制(联网),如需避免联网安装可跳过浏览器登录并手动填入认证文件。若担心,请在受控环境(如容器或虚拟机)中执行首次安装和登录流程。 - 源代码已包含对 yuyue.library.sh.cn 的 API 调用(查询/预约/取消),网络请求目的明确;如果你不信任发布者,建议先在本地审阅脚本或从可信来源(项目主页)验证代码指纹再运行。 - 不要以 root/管理员权限运行脚本;保持 profile 文件权限(例如 chmod 600)以减少凭证泄露风险。 - 如果想更高安全性:在沙箱/容器中安装并运行、逐行审查 login.js/playwright 使用逻辑,或只使用手动获取认证信息的方式(SKILL.md 提供说明)。
详细分析 ▾
用途与能力
技能名/描述与实际代码一致:脚本使用 Node.js + Playwright 做浏览器辅助登录,读取/写入本地 profile 文件,并调用 yuyue.library.sh.cn 的预约 API。所需二进制(node/npm/npx)及 npm 包(playwright)与实现高度匹配,没有请求与功能不相关的云凭证或外部服务密钥。
指令范围
SKILL.md 明确说明运行时行为:可选的浏览器自动化登录(手动完成账号密码/验证码后脚本提取认证信息)、从 ~/.config/shlibrary-seat-booking/profiles/*.json 读取/写入认证、以及对图书馆 API 的查询/预约/取消操作。所有网络请求目标均为图书馆域名,未发现会读取系统其他敏感配置或把数据发到与功能无关的第三方端点。
安装机制
安装规范使用 Homebrew 安装 Node(常见,但会改变本机环境)并通过 npm 安装 playwright;Playwright 运行 npx playwright install chromium 会联网下载 Chromium 二进制。该行为对本功能是合理的,但请注意浏览器二进制会从 Playwright 的发布源下载(联网),这在安全评估中应被记住。
凭证需求
技能不要求任何环境变量或第三方凭证;它使用本地 profile 文件存放 accessToken/sign/timestamp(REQUIRED_AUTH_FIELDS),这与预约 API 所需认证相符。读取和写入 ~/.config/shlibrary-seat-booking 是必要且合理的,SKILL.md 也建议对保存文件设置 chmod 600。
持久化与权限
技能未设置 always:true,也不请求修改其它技能或系统范围配置。它会在本地配置目录下读写自己的 profile 文件,这是预期行为且权限范围有限。技能允许被代理自主调用(disable-model-invocation:false),这是平台默认行为,与代码用途一致。
安全有层次,运行前请审查代码。

License

MIT-0

可自由使用、修改和再分发,无需署名。

运行时依赖

无特殊依赖

版本

latestv0.1.92026/3/20

Use YAML install metadata and declare Playwright npm dependency

● 无害

安装命令 点击复制

官方npx clawhub@latest install shlibrary-seat-booking
镜像加速npx clawhub@latest install shlibrary-seat-booking --registry https://cn.clawhub-mirror.com

技能文档

通过上海图书馆预约接口,预约东馆三楼阅览座位。

功能特性

  • 浏览器辅助登录 - 手动完成登录后,自动获取认证信息
  • 读取本地认证信息 - 从 profile 文件读取认证信息
  • 登录态自动刷新 - profile 文件来源的认证缺失或失效时,会自动拉起登录流程
  • 支持时段标签 - "上午 / 下午 / 晚上"映射到具体时间
  • 支持中文参数值 - 支持 --area 南区 --seat-row 4排 --seat-no 2号 这样的直观输入
  • 整天预约模式 - 一键预约当天所有时段
  • 检查指定座位可用性 - 指定座位预约前自动检查目标座位
  • 提交指定座位预约 - 预约特定座位
  • 系统自动分配预约 - 让系统分配可用座位
  • 查询整天公共可用座位 - 查询某一天全部时段都可用的座位列表
  • 查询当前账号已有预约 - 查看预约记录
  • 取消指定预约 - 取消已有预约
  • 多账号支持 - 通过 --profile 切换不同账号

前置条件

  • 拥有上海图书馆读者证(已开通借阅功能)
  • 已安装依赖(如果使用浏览器登录功能)
  • 如果使用预约模式,需要知道 日期和时段
  • 如果使用指定座位模式,还需要知道 区域、排号和座位号
  • 如果要切换到另一个账号,可以额外准备一个 profile 对应的认证文件
  • 不要求事先手动登录或手动保存认证文件;当使用 profile 文件时,book_seat.js 会在认证缺失或失效时自动拉起登录流程

适用方式

当前推荐统一使用子命令入口:

  • availability:查询某天全部时段都可用的座位
  • list:查询当前账号已有预约
  • cancel:取消指定预约
  • book:预约座位

当前脚本支持两类预约:

  • 指定座位模式:先查这个座位是否可用,再决定是否提交预约
  • 自动分配模式:不指定区域/排号/座位号,直接请求系统分配一个可用座位

参数约定:

  • availability --date [日期] [--area 区域...]
- --date:必填,表示查询哪一天 - --area:可选,表示只扫描哪些区域;不传就查询全部区域
  • list [--profile 名称]
- 不接受其他业务参数
  • cancel --reservation-id [预约ID]
- --reservation-id:必填,只负责指定要取消哪条预约
  • book --date [日期] [--period 时段] [--area 区域] [--seat-row 排号] [--seat-no 座位号]
- 只有 --date:整天自动分配 - --date + --period:单时段自动分配 - --date + --area + --seat-row + --seat-no:整天指定座位 - --date + --period + --area + --seat-row + --seat-no:单时段指定座位 - 参数值支持中文格式,例如:--area 南区 --seat-row 4排 --seat-no 2号

常用命令速查

# 查询当前账号预约
node ./scripts/book_seat.js list

# 查询指定账号预约 node ./scripts/book_seat.js list --profile user1

# 查询 3 月 20 日在多个区域里整天都可用的座位 node ./scripts/book_seat.js availability --profile user1 --date 2026-03-20 --area 北区 西区 东区

# 查询 3 月 20 日全部区域里整天都可用的座位 node ./scripts/book_seat.js availability --profile user1 --date 2026-03-20

# 取消预约 node ./scripts/book_seat.js cancel --profile user1 --reservation-id 5187335

# 按时段自动分配 node ./scripts/book_seat.js book --profile user1 --date 2026-03-24 --period 上午

# 按时段指定座位 node ./scripts/book_seat.js book --profile user1 --date 2026-03-24 --period 下午 --area 南区 --seat-row 4 --seat-no 5

# 整天自动分配 node ./scripts/book_seat.js book --profile user1 --date 2026-03-24

# 整天指定座位 node ./scripts/book_seat.js book --profile user1 --date 2026-03-24 --area 南区 --seat-row 4 --seat-no 5

说明:

  • 不传 --profile 就使用默认账号
  • --profile 会读取默认 profile 根目录下的 profiles/.json
  • 默认 profile 根目录是 ~/.config/shlibrary-seat-booking
  • 也可以通过 --profile-dir--auth-file 显式指定认证文件位置
  • 如果 profile 文件缺失或认证失效,脚本会自动拉起登录

快速开始

方式1: 浏览器自动化登录(推荐)

Skill 提供了基于 Node.js + Playwright 的浏览器自动化脚本,可以自动完成登录并获取认证信息:

安装依赖

# 在 skill 目录内安装 Playwright
cd /path/to/shlibrary-seat-booking
npm install playwright

# 安装浏览器二进制 npx playwright install chromium

说明:

  • 请在 skill 目录内执行 npm install playwright,这样 node ./scripts/*.js 才能稳定加载本地 playwright 依赖
  • npx playwright install chromium 会联网下载 Chromium 浏览器二进制

运行登录脚本

# 默认账号登录
node ./scripts/login.js

# 指定profile登录 node ./scripts/login.js --profile user1

# 指定 profile 根目录 node ./scripts/login.js --profile user1 --profile-dir ~/.config/shlibrary-seat-booking

# 直接指定认证文件 node ./scripts/login.js --auth-file ~/.config/shlibrary-seat-booking/profiles/user1.json

脚本会:

  • 打开浏览器并访问登录页面
  • 由你手动完成用户名、密码、验证码登录
  • 登录成功后自动检测并继续
  • 自动进入 seatyy / service/yuyue,优先直接调用 queryAuthInfo
  • 只有门户没有自动准备好时,才兜底尝试点击“预约”入口
  • 保存到对应的认证文件(默认 ~/.config/shlibrary-seat-booking/profiles/default.json

技术实现

  • 纯 Node.js 实现 - 使用 Playwright 打开浏览器
  • 手动登录 + 自动提取 - 登录动作由你完成,认证提取由脚本完成
  • 优先直连门户接口 - 先走 seatyy -> service/yuyue -> queryAuthInfo
  • 调用 queryAuthInfo - 自动获取 accessTokensigntimestamp
  • 多账号支持 - 通过 --profile 参数管理多个账号

方式2: 手动获取认证信息

如果你更喜欢手动操作,或者想排查认证问题:

  • 先通过门户进入预约系统(通常会经过 service/seatyyservice/yuyue
  • 使用读者证登录
  • 按 F12 打开浏览器开发者工具
  • 切换到 Network(网络)标签
  • 进入任意可触发预约系统接口的页面
  • 查看任意预约 API 请求的 Request Headers
  • 复制以下三个参数:
- accessToken - sign - timestamp
  • x-encode 不需要手动保存,脚本会在每次发请求前动态生成

2. 保存认证信息

如果使用浏览器自动化登录,认证信息会自动保存。

如果手动获取,将认证信息保存到文件:

mkdir -p ~/.config/shlibrary-seat-booking/profiles
cat > ~/.config/shlibrary-seat-booking/profiles/default.json << 'EOF'
{
  "accessToken": "你的accessToken",
  "sign": "你的sign",
  "timestamp": "你的timestamp"
}
EOF
chmod 600 ~/.config/shlibrary-seat-booking/profiles/default.json

注意:

  • 认证信息会失效,但接口没有提供稳定可读的明确过期时间
  • book_seat.js 会先探测登录态;如果认证来自 profile 文件且缺失或失效,会自动拉起 login.js
  • 如果接口返回 code 101 / 获取用户信息时出现异常,脚本也会按失效登录态处理
  • 是否“过期”以接口探测结果为准,不建议只靠本地时间戳人工判断
  • 不要把真实凭证提交到仓库或发给别人

如果你需要管理多个账号,也可以按 profile 名称保存多个文件:

~/.config/shlibrary-seat-booking/profiles/default.json
~/.config/shlibrary-seat-booking/profiles/user1.json
~/.config/shlibrary-seat-booking/profiles/user2.json

认证读取优先级是:

  • --auth-file:直接读取显式指定的单文件
  • --profile-dir + --profile:读取 /profiles/.json
  • 默认 profile 根目录 + --profile:读取 ~/.config/shlibrary-seat-booking/profiles/.json
  • 什么都不传:读取 ~/.config/shlibrary-seat-booking/profiles/default.json

认证写入规则是:

  • 传了 --auth-file:登录成功后写回该文件
  • 传了 --profile-dir + --profile:写 /profiles/.json
  • 只传 --profile:写 ~/.config/shlibrary-seat-booking/profiles/.json
  • 什么都不传:写 ~/.config/shlibrary-seat-booking/profiles/default.json

补充说明:

  • book_seat.js 会先探测登录态;如果 profile 文件缺失或登录态失效,会自动拉起 login.js

3. 预约座位

预约座位

统一使用 book 子命令:

# 整天自动分配
node ./scripts/book_seat.js \
  book --date 2026-03-24

# 单时段自动分配 node ./scripts/book_seat.js \ book --date 2026-03-24 --period 上午

# 整天指定座位 node ./scripts/book_seat.js \ book --date 2026-03-24 --area 南区 --seat-row 4 --seat-no 5

# 单时段指定座位 node ./scripts/book_seat.js \ book --date 2026-03-24 --period 下午 --area 南区 --seat-row 4 --seat-no 5

脚本执行流程:

  • 按优先级读取认证文件
  • 如果认证缺失或失效,自动拉起登录流程
  • 根据参数组合判断是自动分配还是指定座位、整天还是单时段
  • 如果是指定座位,先查询目标时段的可用座位
  • 如果座位可用,再提交预约
  • 输出预约成功或失败信息

系统自动分配

如果你只关心时间段,不关心具体座位,可以让系统自动分配:

# 预约3月22日上午,由系统自动分配座位
node ./scripts/book_seat.js \
  book --date 2026-03-22 --period 上午

自动分配模式的流程:

  • 按优先级读取认证文件
  • 如果认证缺失或失效,自动拉起登录流程
  • 直接调用预约接口,请求系统分配可用座位
  • 输出预约成功或失败信息

也支持按时段标签自动分配:

node ./scripts/book_seat.js \
  book --date 2026-03-22 --period 上午

如果要替另一个账号查预约:

node ./scripts/book_seat.js \
  list --profile user1

4. 查询已有预约

如果你想先确认账号当前已经约了哪些时间段,可以直接查询:

node ./scripts/book_seat.js list

查询模式会:

  • 按优先级读取认证文件
  • 如果认证缺失或失效,自动拉起登录流程
  • 调用"我的预约"接口
  • 按日期分组打印当前账号的预约记录
  • 展示每条记录的时间段、座位、预约状态、预约 ID 和是否可取消

5. 查询整天公共可用座位

如果你想先筛出“某一天全部时段都可用”的位置,可以直接查询。这里日期是必填参数,区域通过 --area 可选传入:

node ./scripts/book_seat.js \
  availability --profile user1 --date 2026-03-20 --area 北区 西区 东区

如果你不指定区域,脚本会自动扫描全部区域:

node ./scripts/book_seat.js \
  availability --profile user1 --date 2026-03-20

这个模式会:

  • 读取对应 profile 的认证信息
  • 如果认证缺失或失效,自动拉起登录流程
  • 根据日期判断当天是 2 个时段还是 3 个时段
  • 扫描目标区域的所有排号和可用座位
  • 计算每个区域在当天全部时段的座位交集
  • 输出每个区域“所有时段都可用”的座位列表

说明:

  • 可以通过 --area 传一个或多个区域,例如 --area 北区 西区 东区
  • 也可以传区域 ID:2 / 3 / 4 / 5
  • 如果不传区域,脚本会扫描全部区域
  • 周一会按 2 个时段求交集,其他日期按 3 个时段求交集
  • 这是只读查询,不会创建任何预约

6. 取消预约

如果你已经知道预约 ID,可以直接取消:

node ./scripts/book_seat.js cancel --reservation-id 5187335

取消模式会:

  • 按优先级读取认证文件
  • 如果认证缺失或失效,自动拉起登录流程
  • 调用取消预约接口
  • 输出成功或失败结果

更稳的使用顺序通常是:

  • 先执行 list
  • 找到目标记录的 预约ID
  • 再执行 cancel --reservation-id [预约ID]

时段映射规则

当前脚本按业务规则使用固定 mapping:

  • 周一
- 下午 -> 13:45:00-16:45:00 - 晚上 -> 17:00:00-20:30:00 - 上午 -> 不可用
  • 周二到周日
- 上午 -> 09:15:00-12:45:00 - 下午 -> 13:00:00-16:30:00 - 晚上 -> 16:45:00-20:15:00

如果图书馆后续调整了开放时段,这部分规则也需要同步更新。

整天预约顺序

当使用整天预约模式时,脚本会按这个顺序逐段尝试:

  • 下午
  • 晚上
  • 上午

这是一种 best-effort 策略:

  • 某一段失败不会中断其他时段
  • 最后会统一汇总成功和失败结果
  • 每个时段提交后会等待约 1 秒,再继续下一段,尽量降低"请勿重复提交"这类频控问题

自动重试策略

当前脚本对部分临时性失败做了短重试:

  • 当接口返回 系统拥挤,请稍后再试
  • 预约和取消都会自动重试
  • 默认最多重试 3
  • 每次重试间隔约 1.5

像这些明确的业务失败不会自动重试:

  • 座位已约满
  • 该时间段有其他预约
  • 目标座位不可用

区域 ID 对照

  • 2: 东区
  • 3: 西区
  • 4: 北区
  • 5: 南区

预约规则

  • 放号时间: 每日12:00开放从当天算起第7天的座位预约
  • 签到时间: 预约开始时间后15分钟内必须扫码签到
  • 取消预约: 可在"我的预约"中提前取消
  • 违规处理: 3次违规将暂停预约权限30天

参考资料

故障排除

认证失败

  • 检查认证信息是否过期
  • 检查 accessTokensigntimestamp 三个字段是否都存在
  • 重新登录获取新的认证信息
  • 如果返回 code 101 / 获取用户信息时出现异常,也按登录态失效处理

座位不可用

  • 该座位可能已被他人预约
  • 脚本会打印当前可用座位列表,可改约其他座位

系统自动分配失败

  • 如果接口返回"该时间段有其他预约",说明当前账号在同一时段已有预约,不能重复预约
  • 如果接口返回无可用座位,需要更换时间段再试

查询已有预约失败

  • 检查认证信息是否过期
  • 如果接口返回登录页或非 JSON,通常是认证失效
  • 如果接口返回 code 101 / 获取用户信息时出现异常,通常也需要重新登录
  • 重新抓取 accessTokensigntimestamp 后重试

取消预约失败

  • 检查该 预约ID 是否存在
  • 确认该记录当前 可取消: 是
  • 如果接口提示状态不允许取消,说明该预约可能已签到、已过期或已取消

接口返回非 JSON 或 HTTP 错误

  • 这通常表示认证失效、请求被拦截、或接口返回了登录页/错误页
  • 先重新获取认证信息,再重试
  • 必要时参考 references/api_reference.md 核对请求参数

API调用失败

  • 检查网络连接
  • 确认认证信息正确
  • 查看脚本输出中的 HTTP 状态码、响应片段和错误信息
数据来源:ClawHub ↗ · 中文优化:龙虾技能库
OpenClaw 技能定制 / 插件定制 / 私有工作流定制

免费技能或插件可能存在安全风险,如需更匹配、更安全的方案,建议联系付费定制

了解定制服务