fish2018/pansou · error
[ ] 请求返回状态码
Error message
[%s] 请求返回状态码: %d
What it means
CldiPlugin.searchPage returns this when the search endpoint responds with a status code other than 200. It reports the plugin name and the actual code but discards the response body, so the reason (block page, rate-limit notice, server error) is not visible. It indicates an upstream/API-level rejection rather than a transport failure.
Solutions
- Read and log a snippet of resp.Body before returning so the actual rejection reason is visible.
- If 429, reduce request rate or honor Retry-After; add backoff in doRequestWithRetry.
- If 403, refresh headers (User-Agent, Referer, cookies) via setRequestHeaders to mimic a real browser.
- Confirm the endpoint path is still valid on the live site.
Example fix
// before
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode != 200 {
snippet, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
return nil, fmt.Errorf("[%s] 请求返回状态码: %d, body: %s", p.Name(), resp.StatusCode, snippet)
} Defensive patterns
Strategy: fallback
Try / catch
results, err := plugin.Search(ctx, keyword)
if err != nil {
if m := regexp.MustCompile(`状态码: (\d+)`).FindStringSubmatch(err.Error()); m != nil {
switch m[1] {
case "429":
// back off / slow down request rate
case "403", "404":
// endpoint blocked or moved: switch to fallback source
}
}
} Prevention
- Throttle scraping to stay under rate limits
- Rotate realistic browser headers and cookies
- Alert on persistent non-200s so endpoint changes are caught quickly
- Capture the response body on non-200 to enable diagnosis
When it happens
Trigger: resp.StatusCode != 200 after doRequestWithRetry succeeds in searchPage — e.g. 403 from anti-bot WAF, 429 rate limit, 503 maintenance, or a changed endpoint returning 404.
Common situations: Scraping too aggressively triggering rate limits, IP banned by the site, site redesign moving the endpoint, or missing/rotated cookies and User-Agent headers.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/4d5c81e1a3bd5cc3.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/cldi/cldi.go:151
// 创建请求
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
}
// 设置请求头
p.setRequestHeaders(req)
// 发送请求
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)
}
// 读取响应
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("[%s] 读取响应失败: %w", p.Name(), err)
}
// 解析HTML
doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(body)))
if err != nil {
return nil, fmt.Errorf("[%s] HTML解析失败: %w", p.Name(), err)
}
// 提取搜索结果
return p.extractSearchResults(doc), nil
}
View on GitHub (pinned to beaa561337)