fish2018/pansou · error
HTTP 403 Forbidden - 需要重新登录
Error message
HTTP 403 Forbidden - 需要重新登录
What it means
The search response body passed isLoginShell(body) — i.e. it looks like the login page shell rather than search results. The plugin interprets this as the server having redirected to login because the session is invalid, and reports it as a 403-like condition requiring re-login.
Solutions
- Re-login to refresh the session cookie (the plugin's 403-recovery path handles this).
- Avoid using the same account from multiple clients that invalidate each other's sessions.
- Persist cookies across restarts so sessions are reused while valid.
- Verify credentials are still valid in case the account was logged out everywhere.
Defensive patterns
Strategy: retry
Try / catch
results, err := p.Search(keyword)
if err != nil && strings.Contains(err.Error(), "需要重新登录") {
if rlErr := p.reloginUser(user); rlErr != nil {
return rlErr
}
results, err = p.Search(keyword)
} Prevention
- Use one session per account — concurrent logins may invalidate each other.
- Re-login proactively when cookies are older than the site's session TTL.
- Persist and reload cookies to detect staleness early.
When it happens
Trigger: searchWithScraper gets HTTP 200 but the HTML is the login shell (session silently invalidated); the code detects isLoginShell(body) and returns this error before attempting JSON extraction.
Common situations: Site logs out sessions server-side ( kicked by concurrent login ); cookies cleared/rotated; site redirects unauthenticated requests to the login page instead of returning 403.
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- login required
- %w: %s
- loginResp.Message (dynamic remote login failure message)
- username cannot be empty
- token cannot be empty
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/ccbe2d446961f26a.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/gying/gying.go:2492
preview := string(body)
if len(preview) > 300 {
preview = preview[:300] + "..."
}
fmt.Printf("[Gying] 403响应内容: %s\n", preview)
}
}
return nil, fmt.Errorf("HTTP 403 Forbidden - 可能需要重新登录")
}
// 2. 提取 _obj.search JSON
matches := searchDataPattern.FindSubmatch(body)
if DebugLog {
fmt.Printf("[Gying] 正则匹配结果: 找到 %d 个匹配\n", len(matches))
}
if isLoginShell(body) {
return nil, fmt.Errorf("HTTP 403 Forbidden - 需要重新登录")
}
if len(matches) < 2 {
if DebugLog {
fmt.Printf("[Gying] ❌ 未找到 _obj.search JSON数据\n")
// 尝试查找是否有其他模式
if strings.Contains(string(body), "_obj.search") {
fmt.Printf("[Gying] 但是Body中包含 '_obj.search' 字符串\n")
} else {
fmt.Printf("[Gying] Body中不包含 '_obj.search' 字符串\n")
}
}
return nil, fmt.Errorf("未找到搜索结果数据")
}
if DebugLog {
jsonStr := string(matches[1])View on GitHub (pinned to beaa561337)