修复 pan.qoark.cn 重定向链接无法正常访问的问题

问题:
- 搜索结果中的 pan.qoark.cn 链接在 qasx 内无法正常访问
- 这些链接实际会重定向到 pan.quark.cn 的真实地址

修复:
- 在 PanSou 搜索结果处理中添加重定向解析,自动获取真实地址
- 在后端 get_share_detail 接口中添加重定向解析
- 前端支持显示和提取 pan.qoark.cn 链接的资源 ID
This commit is contained in:
x1ao4 2026-01-10 15:40:21 +08:00
parent e4ffec9ba4
commit 4bd7d73514
3 changed files with 87 additions and 8 deletions

View File

@ -3521,6 +3521,39 @@ def get_task_suggestions():
return jsonify({"success": True, "message": f"error: {str(e)}"})
def _resolve_qoark_redirect(url: str) -> str:
"""
解析 pan.qoark.cn 链接的重定向地址
如果链接是 pan.qoark.cn则获取重定向后的真实地址
如果不是则直接返回原链接
"""
if not isinstance(url, str) or "pan.qoark.cn" not in url:
return url
try:
# 创建新的 session 用于重定向解析
redirect_session = requests.Session()
redirect_session.max_redirects = 10
# 只获取头信息不获取完整内容HEAD 请求更快)
resp = redirect_session.head(url, allow_redirects=True, timeout=10)
# 如果成功重定向到 pan.quark.cn返回重定向后的地址
if resp.status_code == 200 and "pan.quark.cn" in resp.url:
return resp.url
# 如果 HEAD 请求失败,尝试 GET 请求(某些服务器可能不支持 HEAD
elif resp.status_code != 200:
resp = redirect_session.get(url, allow_redirects=True, timeout=10)
if resp.status_code == 200 and "pan.quark.cn" in resp.url:
return resp.url
# 如果重定向失败或没有重定向到 pan.quark.cn返回原链接
return url
except Exception as e:
# 如果解析失败,返回原链接(避免影响其他功能)
logging.warning(f"解析 pan.qoark.cn 重定向失败: {str(e)}")
return url
# 获取分享详情接口
@app.route("/get_share_detail", methods=["GET", "POST"])
def get_share_detail():
@ -3534,6 +3567,10 @@ def get_share_detail():
else:
shareurl = request.json.get("shareurl", "")
stoken = request.json.get("stoken", "")
# 解析 pan.qoark.cn 链接的重定向地址
if shareurl and "pan.qoark.cn" in shareurl:
shareurl = _resolve_qoark_redirect(shareurl)
account = Quark("", 0)
# 设置account的必要属性

View File

@ -23,6 +23,38 @@ class PanSou:
return resp.json()
except Exception as e:
return {"success": False, "message": str(e)}
def _resolve_qoark_redirect(self, url: str) -> str:
"""
解析 pan.qoark.cn 链接的重定向地址
如果链接是 pan.qoark.cn则获取重定向后的真实地址
如果不是则直接返回原链接
"""
if not isinstance(url, str) or "pan.qoark.cn" not in url:
return url
try:
# 创建新的 session 用于重定向解析(避免影响主 session
redirect_session = requests.Session()
redirect_session.max_redirects = 10
# 只获取头信息不获取完整内容HEAD 请求更快)
resp = redirect_session.head(url, allow_redirects=True, timeout=10)
# 如果成功重定向到 pan.quark.cn返回重定向后的地址
if resp.status_code == 200 and "pan.quark.cn" in resp.url:
return resp.url
# 如果 HEAD 请求失败,尝试 GET 请求(某些服务器可能不支持 HEAD
elif resp.status_code != 200:
resp = redirect_session.get(url, allow_redirects=True, timeout=10)
if resp.status_code == 200 and "pan.quark.cn" in resp.url:
return resp.url
# 如果重定向失败或没有重定向到 pan.quark.cn返回原链接
return url
except Exception as e:
# 如果解析失败,返回原链接(避免影响其他功能)
# 可以在这里添加日志记录错误
return url
def _get_pansou_source(self, result_item: dict, merged_item: dict = None) -> str:
"""
@ -116,6 +148,8 @@ class PanSou:
url = link.get("url", "")
link_type = link.get("type", "")
if url: # 确保有有效链接
# 解析 pan.qoark.cn 链接的重定向地址
url = self._resolve_qoark_redirect(url)
cleaned.append({
"taskname": title,
"content": content,
@ -144,6 +178,8 @@ class PanSou:
pansou_source = self._get_pansou_source(None, link)
if url:
# 解析 pan.qoark.cn 链接的重定向地址
url = self._resolve_qoark_redirect(url)
cleaned.append({
"taskname": note,
"content": note, # 如果没有 content使用 note
@ -158,10 +194,14 @@ class PanSou:
if not cleaned and isinstance(payload, list):
for item in payload:
if isinstance(item, dict):
url = item.get("url", "")
# 解析 pan.qoark.cn 链接的重定向地址
if url:
url = self._resolve_qoark_redirect(url)
cleaned.append({
"taskname": item.get("title", ""),
"content": item.get("content", ""),
"shareurl": item.get("url", ""),
"shareurl": url,
"tags": item.get("tags", []) or [],
"publish_date": item.get("datetime", ""), # 原始时间
"source": "PanSou", # 添加来源标识
@ -178,8 +218,8 @@ class PanSou:
try:
url = item.get("shareurl", "")
tags = item.get("tags", []) or []
# 检查是否为夸克网盘
is_quark = ("quark" in tags) or ("pan.quark.cn" in url)
# 检查是否为夸克网盘(支持 pan.quark.cn 和已解析的 pan.qoark.cn
is_quark = ("quark" in tags) or ("pan.quark.cn" in url) or ("pan.qoark.cn" in url)
if is_quark:
filtered.append(item)
except Exception:

View File

@ -1260,7 +1260,7 @@
<div v-for="suggestion in smart_param.taskSuggestions.data || []" :key="(suggestion.shareurl || '') + '_' + (suggestion.taskname || '') + '_' + (suggestion.publish_date || '')" class="dropdown-item cursor-pointer" @click.prevent="selectSuggestion(task.__originalIndex !== undefined ? task.__originalIndex : index, suggestion)" style="font-size: 14px;" :title="getSuggestionHoverTitle(suggestion)">
<span v-html="suggestion.verify ? '✅': ''"></span> {{ suggestion.taskname }}
<small class="text-muted">
<a :href="suggestion.shareurl" target="_blank" @click.stop> · {{ suggestion.shareurl.replace(/^https?:\/\/pan\.quark\.cn\/s\//, '') }}</a>
<a :href="suggestion.shareurl" target="_blank" @click.stop> · {{ suggestion.shareurl.replace(/^https?:\/\/pan\.(quark|qoark)\.cn\/s\//, '') }}</a>
<template v-if="suggestion.source"><span class="source-badge" :class="suggestion.source.toLowerCase()" :data-publish-date="suggestion.publish_date ? ' · ' + formatPublishDate(suggestion.publish_date, suggestion.pansou_source, suggestion.source) : ''">{{ suggestion.source }}</span></template>
</small>
</div>
@ -2793,7 +2793,7 @@
<div v-for="suggestion in smart_param.taskSuggestions.data || []" :key="(suggestion.shareurl || '') + '_' + (suggestion.taskname || '') + '_' + (suggestion.publish_date || '')" class="dropdown-item cursor-pointer" @click.prevent="selectSuggestion(-1, suggestion)" style="font-size: 14px;" :title="getSuggestionHoverTitle(suggestion)">
<span v-html="suggestion.verify ? '✅': ''"></span> {{ suggestion.taskname }}
<small class="text-muted">
<a :href="suggestion.shareurl" target="_blank" @click.stop> · {{ suggestion.shareurl.replace(/^https?:\/\/pan\.quark\.cn\/s\//, '') }}</a>
<a :href="suggestion.shareurl" target="_blank" @click.stop> · {{ suggestion.shareurl.replace(/^https?:\/\/pan\.(quark|qoark)\.cn\/s\//, '') }}</a>
<template v-if="suggestion.source"><span class="source-badge" :class="suggestion.source.toLowerCase()" :data-publish-date="suggestion.publish_date ? ' · ' + formatPublishDate(suggestion.publish_date, suggestion.pansou_source, suggestion.source) : ''">{{ suggestion.source }}</span></template>
</small>
</div>
@ -10407,9 +10407,11 @@
if (!shareurl) return null;
try {
// 夸克网盘分享链接格式https://pan.quark.cn/s/资源ID
const match = shareurl.match(/pan\.quark\.cn\/s\/([a-zA-Z0-9]+)/);
return match ? match[1] : null;
// 夸克网盘分享链接格式:
// https://pan.quark.cn/s/资源ID 或 https://pan.qoark.cn/s/资源ID
// 支持 pan.quark.cn 和 pan.qoark.cn
const match = shareurl.match(/pan\.(quark|qoark)\.cn\/s\/([a-zA-Z0-9]+)/);
return match ? match[2] : null;
} catch (e) {
return null;
}