fish2018/pansou · error
[ ] 搜索请求HTTP状态错误
Error message
[%s] 搜索请求HTTP状态错误: %d
What it means
dyyj.executeSearchHTML received a non-200 HTTP status from the search page. The plugin treats anything other than 200 as a failure and includes the status code in the error message. Common codes: 403 (bot blocked), 503 (challenge/overload), 404 (path changed), 5xx (server error).
Solutions
- Log the body on non-200 — the plugin already reads it; check for Cloudflare/challenge HTML
- Add/refresh cookies and realistic headers (User-Agent already set) to pass the WAF
- Back off longer on 429/503 and retry after a delay
- Verify the search URL path is still valid (404 means the site changed)
- Consider a headless-browser fallback if the site requires JS challenges
Example fix
// before
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] 搜索请求HTTP状态错误: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode == http.StatusServiceUnavailable {
time.Sleep(retryBackoff)
// retry once more before failing
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("[%s] 搜索请求HTTP状态错误: %d", p.Name(), resp.StatusCode)
} Defensive patterns
Strategy: retry
Validate before calling
resp, err := http.Head(probeURL)
if err == nil && resp.StatusCode != http.StatusOK { return fmt.Errorf("search endpoint unhealthy: %d", resp.StatusCode) } Try / catch
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
if resp.StatusCode == 429 || resp.StatusCode == 503 {
// honor Retry-After and back off
}
return nil, fmt.Errorf("non-200 (%d): body=%q", resp.StatusCode, body)
} Prevention
- Send realistic headers and keep cookies to pass anti-bot checks
- Honor Retry-After on 429/503 with real backoff
- Alert on persistent 403/404 — the site path or WAF rules changed
- Log a body snippet on every non-200 for diagnosis
When it happens
Trigger: The server responded successfully at the transport level but with status != 200 after doRequestWithRetry (retries did not produce a 200).
Common situations: Anti-bot WAF returning 403 due to missing/rotated cookies or fingerprinting; site rate limiting (429); search path changed (404); temporary 5xx during site maintenance.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/db6197acd5c62b17.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/dyyj/dyyj.go:270
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
if p.debugMode {
log.Printf("[DYYJ] 搜索请求失败: %v", err)
}
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
if p.debugMode {
log.Printf("[DYYJ] 搜索请求响应状态码: %d", resp.StatusCode)
}
if resp.StatusCode != 200 {
if p.debugMode {
log.Printf("[DYYJ] 搜索请求HTTP状态错误: %d", resp.StatusCode)
}
return nil, fmt.Errorf("[%s] 搜索请求HTTP状态错误: %d", p.Name(), resp.StatusCode)
}
// 读取响应体用于调试
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
if p.debugMode {
log.Printf("[DYYJ] 读取响应体失败: %v", err)
}
return nil, fmt.Errorf("[%s] 读取响应体失败: %w", p.Name(), err)
}
bodyString := string(bodyBytes)
if p.debugMode {
log.Printf("[DYYJ] 响应体大小: %d 字节", len(bodyString))
// 保存完整HTML到文件用于分析
filename := fmt.Sprintf("./dyyj_search_%s_%d.html", url.QueryEscape(keyword), time.Now().Unix())
if err := os.WriteFile(filename, bodyBytes, 0644); err == nil {View on GitHub (pinned to beaa561337)