fish2018/pansou · error
[ ] 搜索请求返回状态码
Error message
[%s] 搜索请求返回状态码: %d
What it means
Raised in Muou's searchAtBase when the search response completed but the HTTP status is not 200. The plugin treats any non-200 as a failed search for this base URL and returns so the caller can try another base.
Solutions
- Log the exact status code and response headers to identify blocking vs server error
- Send complete browser-like headers (User-Agent, Referer, Accept-Language) to reduce 403s
- Implement/increase retry with backoff for 429 and 5xx responses
- Verify the search endpoint path against the current site layout
- Ensure redirects are followed (default http.Client behavior; check custom CheckRedirect)
Example fix
// before
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] 搜索请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode != http.StatusOK {
if resp.StatusCode == http.StatusTooManyRequests {
time.Sleep(5 * time.Second)
return p.searchAtBase(client, baseURL, keyword) // one retry after cooldown
}
return nil, fmt.Errorf("[%s] 搜索请求返回状态码: %d", p.Name(), resp.StatusCode)
} Defensive patterns
Strategy: retry
Validate before calling
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...")
req.Header.Set("Referer", baseURL + "/")
// pre-flight:
resp, err := client.Head(baseURL)
if err == nil && resp.StatusCode == http.StatusForbidden {
log.Printf("blocked by WAF; refresh cookies/headers before searching")
} Try / catch
if resp.StatusCode != http.StatusOK {
if isRetryable(resp.StatusCode) { // 429, 500, 502, 503
backoff(); continue
}
return nil, fmt.Errorf("search status %d", resp.StatusCode)
} Prevention
- Send complete realistic browser headers
- Throttle request rate to avoid 429s
- Retry only retryable statuses (429/5xx), fail fast on 4xx
- Re-verify endpoint paths when the site redesigns
When it happens
Trigger: Triggered when resp.StatusCode != 200: 403 (anti-bot/WAF block), 404 (path changed), 429 (rate limited), 5xx (server error), or 301/302 not followed due to redirect policy.
Common situations: Anti-scraping WAF blocking datacenter IPs; site redesigned and moved the search endpoint; rate limiting after rapid sequential searches; mirror serving stale redirects.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/3c3dd2a7072939ce.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/muou/muou.go:224
// 4. 设置完整的请求头(避免反爬虫)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Upgrade-Insecure-Requests", "1")
req.Header.Set("Cache-Control", "max-age=0")
req.Header.Set("Referer", strings.TrimRight(baseURL, "/")+"/")
// 5. 发送请求(带重试机制)
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] 搜索请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// 6. 解析搜索结果页面
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return nil, fmt.Errorf("[%s] 解析搜索页面失败: %w", p.Name(), err)
}
// 7. 提取搜索结果
var results []model.SearchResult
doc.Find(".module-search-item").Each(func(i int, s *goquery.Selection) {
result := p.parseSearchItem(s, keyword)
if result.UniqueID != "" {
results = append(results, result)
}
})
View on GitHub (pinned to beaa561337)