fish2018/pansou · error
[ ] 第 页请求返回状态码
Error message
[%s] 第%d页请求返回状态码: %d
What it means
searchPage rejects the response for page N because resp.StatusCode != 200, treating it as a failed page fetch. The dy4k site returned an error/challenge status instead of the expected HTML listing. This is upstream behavior (blocking, rate limiting, or site errors), not a caller bug.
Solutions
- Log the status code (already done via debugPrintf) and capture a body snippet to confirm whether it's a WAF challenge.
- Stop paginating on 404 and treat it as end-of-results rather than an error.
- Add delays between page requests and back off on 429 to stay under rate limits.
- Use realistic browser headers (full UA, Accept, Accept-Language, Referer) or rotate proxies if 403 persists.
Example fix
// before
if resp.StatusCode != 200 {
return nil, 0, fmt.Errorf("[%s] 第%d页请求返回状态码: %d", p.Name(), page, resp.StatusCode)
}
// after
if resp.StatusCode == 404 {
return nil, 0, nil // end of results
}
if resp.StatusCode != 200 {
return nil, 0, fmt.Errorf("[%s] 第%d页请求返回状态码: %d", p.Name(), page, resp.StatusCode)
} Defensive patterns
Strategy: retry
Try / catch
if resp.StatusCode != 200 {
switch {
case resp.StatusCode == 429:
time.Sleep(backoff) // then retry
case resp.StatusCode == 404:
return nil, 0, nil // end of pagination
default:
return nil, 0, fmt.Errorf("page %d: status %d", page, resp.StatusCode)
}
} Prevention
- Throttle pagination requests to avoid 429.
- Treat 404 as end-of-results, not failure.
- Use full realistic browser headers to pass WAFs.
- Rotate UA/proxy if 403s recur during scraping.
When it happens
Trigger: The GET for page N completes but returns 403 (anti-bot/WAF), 429 (rate limit from paginating too fast), 404 (page beyond available results), or 5xx (server error).
Common situations: Rapid multi-page scraping triggers rate limiting; random UA/IP tricks fail against Cloudflare; requesting pages past the last result page returns 404; site under maintenance returns 5xx.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/eb413eb72b68098b.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/dy4k/dy4k.go:415
fmt.Printf(" URL错误: %v\n", netErr.Err)
if netErr.Timeout() {
fmt.Printf(" -> 这是超时错误\n")
}
if netErr.Temporary() {
fmt.Printf(" -> 这是临时错误\n")
}
}
return nil, 0, fmt.Errorf("[%s] 第%d页搜索请求失败: %w", p.Name(), page, err)
}
defer resp.Body.Close()
debugPrintf("✅ [Dy4k DEBUG] HTTP请求成功 (耗时: %v)\n", requestDuration)
// 6. 检查状态码
debugPrintf("🔧 [Dy4k DEBUG] HTTP响应状态码: %d\n", resp.StatusCode)
if resp.StatusCode != 200 {
debugPrintf("❌ [Dy4k DEBUG] 状态码异常: %d\n", resp.StatusCode)
return nil, 0, fmt.Errorf("[%s] 第%d页请求返回状态码: %d", p.Name(), page, resp.StatusCode)
}
// 7. 读取并打印HTML响应
htmlBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, 0, fmt.Errorf("[%s] 第%d页读取响应失败: %w", p.Name(), page, err)
}
htmlContent := string(htmlBytes)
debugPrintf("🔧 [Dy4k DEBUG] 第%d页 HTML长度: %d bytes\n", page, len(htmlContent))
// 保存HTML到文件(仅在调试模式下)
if DebugMode {
htmlDir := "./html"
os.MkdirAll(htmlDir, 0755)
filename := fmt.Sprintf("dy4k_page_%d_%s.html", page, strings.ReplaceAll(encodedKeyword, "%", "_"))
filepath := filepath.Join(htmlDir, filename)View on GitHub (pinned to beaa561337)