PanSou是一款高性能的网盘资源搜索API服务,支持TG频道和插件搜索。系统设计以性能和可扩展性为核心,支持多频道多插件并发搜索、结果智能排序和网盘类型分类。docker集成前后端,一键启动,开箱即用。仅供学习研究,请勿以各种形式用于盈利目的。
PanSou是一款高性能的网盘资源搜索API服务,支持TG频道和插件搜索。系统设计以性能和可扩展性为核心,支持多频道多插件并发搜索、结果智能排序和网盘类型分类。docker集成前后端,一键启动,开箱即用。仅供学习研究,请勿以各种形式用于盈利目的。
PanSou是一个高性能的网盘资源搜索API服务,支持TG搜索和自定义插件搜索。系统设计以性能和可扩展性为核心,支持并发搜索、结果智能排序和网盘类型分类。
百度网盘 (baidu)、阿里云盘 (aliyun)、夸克网盘 (quark)、光鸭云盘 (guangya)、天翼云盘 (tianyi)、UC网盘 (uc)、移动云盘 (mobile)、115网盘 (115)、PikPak (pikpak)、迅雷网盘 (xunlei)、123网盘 (123)、磁力链接 (magnet)、电驴链接 (ed2k)、其他 (others)
qqpd搜索插件文档
gying搜索插件文档
weibo搜索插件文档
常见问题总结
TG/QQ频道/插件/微博
一键启动,开箱即用
docker run -d --name pansou -p 80:80 ghcr.io/fish2018/pansou-web
使用Docker Compose(推荐)
# 下载配置文件
curl -o docker-compose.yml https://raw.githubusercontent.com/fish2018/pansou-web/refs/heads/main/docker-compose.yml
# 启动服务
docker-compose up -d
# 查看日志
docker-compose logs -f
docker run -d --name pansou -p 8888:8888 ghcr.io/fish2018/pansou:latest
使用Docker Compose(推荐)
# 下载配置文件
curl -o docker-compose.yml https://raw.githubusercontent.com/fish2018/pansou/refs/heads/main/docker-compose.yml
# 启动服务
docker-compose up -d
# 访问服务
http://localhost:8888
git clone https://github.com/fish2018/pansou.git
cd pansou
8888
修改服务监听端口
PROXY
SOCKS5代理
无
如:PROXY=socks5://127.0.0.1:1080
HTTPS_PROXY/HTTP_PROXY
HTTPS/HTTP代理
无
如:HTTPS_PROXY=http://127.0.0.1:1080,HTTP_PROXY=http://127.0.0.1:1080
CHANNELS
默认搜索的TG频道
tgsearchers3
多个频道用逗号分隔
ENABLED_PLUGINS
指定启用插件,多个插件用逗号分隔
无
必须显式指定
PanSou支持可选的安全认证功能,默认关闭。开启后,所有API接口(除登录接口外)都需要提供有效的JWT Token。详见认证系统设计文档。
环境变量 描述 默认值 说明 AUTH_ENABLED 是否启用认证false
设置为true启用认证功能
AUTH_USERS
用户账号配置
无
格式:user1:pass1,user2:pass2
AUTH_TOKEN_EXPIRY
Token有效期(小时)
24
JWT Token的有效时长
AUTH_JWT_SECRET
JWT签名密钥
自动生成
用于签名Token,建议手动设置
认证配置示例:
# 启用认证并配置单个用户
docker run -d --name pansou -p 8888:8888 \
-e AUTH_ENABLED=true \
-e AUTH_USERS=admin:admin123 \
-e AUTH_TOKEN_EXPIRY=24 \
ghcr.io/fish2018/pansou:latest
# 配置多个用户
docker run -d --name pansou -p 8888:8888 \
-e AUTH_ENABLED=true \
-e AUTH_USERS=admin:pass123,user1:pass456,user2:pass789 \
ghcr.io/fish2018/pansou:latest
认证API接口:
POST /api/auth/login - 用户登录,获取TokenPOST /api/auth/verify - 验证Token有效性POST /api/auth/logout - 退出登录(客户端删除Token)使用Token调用API:
# 1. 登录获取Token
curl -X POST http://localhost:8888/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
# 响应:{"token":"eyJhbGc...","expires_at":1234567890,"username":"admin"}
# 2. 使用Token调用搜索API
curl -X POST http://localhost:8888/api/search \
-H "Authorization: Bearer eyJhbGc..." \
-H "Content-Type: application/json" \
-d '{"kw":"速度与激情"}'
60
CACHE_MAX_SIZE
最大缓存大小(MB)
100
PLUGIN_TIMEOUT
插件超时时间(秒)
30
ASYNC_RESPONSE_TIMEOUT
快速响应超时(秒)
4
ASYNC_LOG_ENABLED
异步插件详细日志
true
CACHE_PATH
缓存文件路径
./cache
SHARD_COUNT
缓存分片数量
8
CACHE_WRITE_STRATEGY
缓存写入策略(immediate/hybrid)
hybrid
ENABLE_COMPRESSION
是否启用压缩
false
MIN_SIZE_TO_COMPRESS
最小压缩阈值(字节)
1024
GC_PERCENT
Go GC触发百分比
50
ASYNC_MAX_BACKGROUND_WORKERS
最大后台工作者数量
CPU核心数×5
ASYNC_MAX_BACKGROUND_TASKS
最大后台任务数量
工作者数×5
ASYNC_CACHE_TTL_HOURS
异步缓存有效期(小时)
1
ASYNC_PLUGIN_ENABLED
异步插件是否启用
true
HTTP_READ_TIMEOUT
HTTP读取超时(秒)
自动计算
HTTP_WRITE_TIMEOUT
HTTP写入超时(秒)
自动计算
HTTP_IDLE_TIMEOUT
HTTP空闲超时(秒)
120
HTTP_MAX_CONNS
HTTP最大连接数
自动计算
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -extldflags '-static'" -o pansou .
./pansou
…
点击展开 nginx 配置参考…
当启用认证功能(AUTH_ENABLED=true)时,除登录和健康检测接口外的所有API接口都需要提供有效的JWT Token。
请求头格式:
Authorization: Bearer <your-jwt-token>
获取Token:
Authorization: Bearer <token>示例:
# 未启用认证时
curl -X POST http://localhost:8888/api/search \
-H "Content-Type: application/json" \
-d '{"kw":"速度与激情"}'
# 启用认证时
curl -X POST http://localhost:8888/api/search \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGc..." \
-d '{"kw":"速度与激情"}'
获取JWT Token用于后续API调用。
接口地址:/api/auth/login
请求方法:POST
Content-Type:application/json
是否需要认证:否
请求参数:
参数名 类型 必填 描述 username string 是 用户名 password string 是 密码请求示例:
curl -X POST http://localhost:8888/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
成功响应:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_at": 1234567890,
"username": "admin"
}
错误响应:
{
"error": "用户名或密码错误"
}
验证当前Token是否有效。
接口地址:/api/auth/verify
请求方法:POST
是否需要认证:是
请求示例:
curl -X POST http://localhost:8888/api/auth/verify \
-H "Authorization: Bearer eyJhbGc..."
成功响应:
{
"valid": true,
"username": "admin"
}
退出当前登录(客户端删除Token即可)。
接口地址:/api/auth/logout
请求方法:POST
是否需要认证:否
请求示例:
curl -X POST http://localhost:8888/api/auth/logout
成功响应:
{
"message": "退出成功"
}
搜索网盘资源。
接口地址:/api/search
请求方法:POST 或 GET
Content-Type:application/json(POST方法)
是否需要认证:取决于AUTH_ENABLED配置
POST请求参数:
参数名 类型 必填 描述 kw string 是 搜索关键词 channels string[] 否 搜索的频道列表,不提供则使用默认配置 conc number 否 并发搜索数量,不提供则自动设置为频道数+插件数+10 refresh boolean 否 强制刷新,不使用缓存,便于调试和获取最新数据 res string 否 结果类型:all(返回所有结果)、results(仅返回results)、merge(仅返回merged_by_type),默认为merge src string 否 数据来源类型:all(默认,全部来源)、tg(仅Telegram)、plugin(仅插件) plugins string[] 否 指定搜索的插件列表,不指定则搜索全部插件 cloud_types string[] 否 指定返回的网盘类型列表,支持:baidu、aliyun、quark、guangya、tianyi、uc、mobile、115、pikpak、xunlei、123、magnet、ed2k,不指定则返回所有类型 ext object 否 扩展参数,用于传递给插件的自定义参数,如{"title_en":"English Title", "is_all":true} filter object 否 过滤配置,用于过滤返回结果。格式:{"include":["关键词1","关键词2"],"exclude":["排除词1","排除词2"]}。include为包含关键词列表(OR关系),exclude为排除关键词列表(OR关系)GET请求参数:
参数名 类型 必填 描述 kw string 是 搜索关键词 channels string 否 搜索的频道列表,使用英文逗号分隔多个频道,不提供则使用默认配置 conc number 否 并发搜索数量,不提供则自动设置为频道数+插件数+10 refresh boolean 否 强制刷新,设置为"true"表示不使用缓存 res string 否 结果类型:all(返回所有结果)、results(仅返回results)、merge(仅返回merged_by_type),默认为merge src string 否 数据来源类型:all(默认,全部来源)、tg(仅Telegram)、plugin(仅插件) plugins string 否 指定搜索的插件列表,使用英文逗号分隔多个插件名,不指定则搜索全部插件 cloud_types string 否 指定返回的网盘类型列表,使用英文逗号分隔多个类型,支持:baidu、aliyun、quark、guangya、tianyi、uc、mobile、115、pikpak、xunlei、123、magnet、ed2k,不指定则返回所有类型 ext string 否 JSON格式的扩展参数,用于传递给插件的自定义参数,如{"title_en":"English Title", "is_all":true} filter string 否 JSON格式的过滤配置,用于过滤返回结果。格式:{"include":["关键词1","关键词2"],"exclude":["排除词1","排除词2"]}POST请求示例:
…
GET请求示例:
# 未启用认证
curl "http://localhost:8888/api/search?kw=速度与激情&res=merge&src=tg"
# 启用认证时(需要添加Authorization头)
curl "http://localhost:8888/api/search?kw=速度与激情&res=merge" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
# 使用过滤器(GET方式需要URL编码JSON)
curl "http://localhost:8888/api/search?kw=唐朝诡事录&filter=%7B%22include%22%3A%5B%22合集%22%2C%22全集%22%5D%2C%22exclude%22%3A%5B%22预告%22%5D%7D"
成功响应:
…
字段说明:
SearchResult对象:
message_id: 消息IDunique_id: 全局唯一标识符channel: 来源频道名称datetime: 消息发布时间title: 消息标题content: 消息内容links: 网盘链接数组tags: 标签数组(可选)images: TG消息中的图片链接数组(可选)Link对象:
type: 网盘类型(baidu、quark、aliyun等)url: 网盘链接地址password: 提取码/密码datetime: 链接更新时间(可选)work_title: 作品标题(可选)MergedLink对象:
url: 网盘链接地址password: 提取码/密码note: 资源说明/标题datetime: 链接更新时间source: 数据来源标识tg:频道名称: 来自Telegram频道plugin:插件名: 来自指定插件unknown: 未知来源images: TG消息中的图片链接数组(可选)错误响应:
// 参数错误
{
"code": 400,
"message": "关键词不能为空"
}
// 未授权(启用认证但未提供Token)
{
"error": "未授权:缺少认证令牌",
"code": "AUTH_TOKEN_MISSING"
}
// Token无效或过期
{
"error": "未授权:令牌无效或已过期",
"code": "AUTH_TOKEN_INVALID"
}
检测指定网盘分享链接当前是否有效,适合前端结果页按需做可见项检测,也支持批量调试和服务端缓存复用。
接口地址:/api/check/links
请求方法:POST
Content-Type:application/json
是否需要认证:取决于AUTH_ENABLED配置
请求参数:
参数名 类型 必填 描述 items object[] 是 待检测链接数组,至少提供一项 items[].disk_type string 是 网盘类型,支持:baidu、aliyun、quark、tianyi、uc、mobile、115、xunlei、123 items[].url string 是 完整分享链接 items[].password string 否 提取码/密码,未拼接在链接中时可传 proxy_url string 否 本次检测请求使用的代理地址,位于请求根节点,支持http://、https://、socks5://、socks5h://
proxy
string
否
proxy_url 的兼容别名,位于请求根节点;同时传入时以 proxy_url 为准
view_token
string
否
视图标识,用于区分当前前端检测批次
代理行为说明:
proxy_url/proxy 只影响当前 /api/check/links 请求,不会修改服务进程的全局代理配置。proxy_url/proxy 时,检测服务沿用启动时的全局HTTP客户端配置。400,不会静默降级为直连。请求示例:
…
成功响应:
…
状态说明:
ok:链接有效bad:链接失效locked:需要提取码或密码错误unsupported:当前平台暂不支持检测uncertain:检测失败或结果不确定字段说明:
results: 检测结果数组results[].disk_type: 网盘类型results[].url: 原始传入链接results[].normalized_url: 规范化后的链接results[].state: 检测状态results[].cache_hit: 是否命中服务端检测缓存results[].checked_at: 最近一次检测时间戳(毫秒)results[].expires_at: 当前缓存过期时间戳(毫秒)results[].summary: 状态说明文本错误响应:
// 请求参数无效
{
"code": 400,
"message": "无效的检测请求: Key: 'CheckRequest.Items' Error:Field validation for 'Items' failed on the 'required' tag"
}
// items 为空
{
"code": 400,
"message": "items不能为空"
}
// 代理参数无效
{
"code": 400,
"message": "无效的代理参数: 不支持的代理协议: ftp"
}
// 未授权(启用认证但未提供Token)
{
"error": "未授权:缺少认证令牌",
"code": "AUTH_TOKEN_MISSING"
}
``