fish2018/pansou · error
未获取到重定向URL
Error message
未获取到重定向URL
What it means
searchPage relies on the first request returning a 30x redirect whose Location header points to the real search-results URL. If the response carries no Location header — the site returned a normal page (200), an error page, or was redirect-handled differently — the plugin cannot proceed and throws "未获取到重定向URL".
Solutions
- Log resp.StatusCode and a body snippet when Location is empty to see what the server actually returned.
- Check if the site now requires login/captcha for search and update the plugin flow accordingly.
- Verify the search URL format still matches the current Discuz redirect behavior (site version change).
- Add retry with backoff in case of transient anti-bot challenges.
- Update User-Agent/headers if the site began fingerprinting clients.
Example fix
// before
location := resp.Header.Get("Location")
if location == "" {
return nil, fmt.Errorf("未获取到重定向URL")
}
// after
location := resp.Header.Get("Location")
if location == "" {
return nil, fmt.Errorf("未获取到重定向URL (status=%d)", resp.StatusCode)
} Defensive patterns
Strategy: fallback
Validate before calling
// Go: sanity-check that the site still behaves as expected before relying on the flow resp, _ := http.Head(baseURL + "/search.php") // if StatusOK without redirect, the redirect-flow assumption is broken
Try / catch
results, err := plugin.Search(keyword, page)
if err != nil && strings.Contains(err.Error(), "未获取到重定向URL") {
log.Printf("panwiki flow changed (site update or anti-bot): %v", err)
// switch to fallback plugin/source
} Prevention
- Add integration tests asserting the redirect-flow still works.
- Log status code and body head when Location is empty.
- Watch for upstream site updates; pin a monitor on the search endpoint.
- Treat repeated occurrences as a signal the scraper needs updating, not a transient fault.
When it happens
Trigger: resp.Header.Get("Location") is empty after the initial request. Happens when the Discuz forum stopped issuing the searchid redirect (e.g. serving results directly, requiring login, showing a captcha/anti-bot page, or returning 200 with an error), or when the site is reachable but behaves differently from what the scraper expects.
Common situations: Upstream site layout/flow changed (site update), anti-bot protection serving a 200 challenge page, search blocked for anonymous users requiring login, rate limiting returning a normal page instead of redirect.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/beb9a9871a8fc41d.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/panwiki/panwiki.go:207
p.setRequestHeaders(req)
resp, err = client.Do(req)
if err != nil {
return nil, fmt.Errorf("备用域名请求也失败: %w", err)
}
} else {
return nil, fmt.Errorf("初始请求失败: %w", err)
}
}
defer resp.Body.Close()
// 重置重定向策略
client.CheckRedirect = nil
// 获取重定向URL
location := resp.Header.Get("Location")
if location == "" {
return nil, fmt.Errorf("未获取到重定向URL")
}
// 构建完整的重定向URL
var searchURL string
if strings.HasPrefix(location, "http") {
searchURL = location
} else {
searchURL = p.currentBaseURL + "/" + strings.TrimPrefix(location, "/")
}
// 如果不是第一页,修改URL中的page参数
if page > 1 {
if strings.Contains(searchURL, "searchid=") {
// 提取searchid并构建分页URL
re := regexp.MustCompile(`searchid=(\d+)`)
matches := re.FindStringSubmatch(searchURL)
if len(matches) > 1 {
searchid := matches[1]View on GitHub (pinned to beaa561337)