fish2018/pansou · error
[ ] 请求返回状态码
Error message
[%s] 请求返回状态码: %d
What it means
jutoushe searchImpl returns this when the HTTP response status code is anything other than 200 after a successful request. It indicates the site responded but rejected the scrape attempt (or the page moved). No body inspection is done before failing.
Solutions
- Log the actual status code and response body snippet to identify the cause
- Refresh the User-Agent and other headers to a current browser value
- Add backoff/rate-limiting between scrape requests to avoid 429/403
- Handle redirects (check if 3xx and follow to the new URL structure)
Example fix
// before
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode != 200 {
body, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
return nil, fmt.Errorf("[%s] 请求返回状态码: %d, body: %s", p.Name(), resp.StatusCode, body)
} Defensive patterns
Strategy: retry
Validate before calling
resp, err := http.Head(baseURL + "/")
if err != nil || resp.StatusCode == http.StatusForbidden {
return errors.New("target site is blocking requests; adjust headers/proxy first")
} Try / catch
results, err := plugin.Search(keyword)
if err != nil {
var statusErr interface{ Error() string }
if strings.Contains(err.Error(), "请求返回状态码") {
log.Printf("non-200 from source, backing off: %v", err)
return backoffAndRetry(err)
}
return err
} Prevention
- Keep browser headers (User-Agent, Accept) current
- Rate-limit scraping to avoid 403/429
- Log status codes and body snippets for diagnosis
- Handle known redirect/changed routes explicitly
When it happens
Trigger: Any non-200 status from the search endpoint: 403 (bot blocking), 404 (page moved), 429 (rate limit), 5xx (server error).
Common situations: Site added WAF/anti-bot protection rejecting the fixed Chrome/91 User-Agent; search path changed; request throttled after frequent scraping.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/7c3d3eb2866c1e56.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/jutoushe/jutoushe.go:76
}
// 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("Referer", baseURL+"/")
// 5. 发送HTTP请求(带重试机制)
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
// 6. 检查状态码
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// 7. 解析搜索结果页面
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return nil, fmt.Errorf("[%s] HTML解析失败: %w", p.Name(), err)
}
// 8. 提取搜索结果
var results []model.SearchResult
doc.Find("ul.erx-list li.item").Each(func(i int, s *goquery.Selection) {
// 提取标题和链接
linkElem := s.Find(".a a.main")
title := strings.TrimSpace(linkElem.Text())
detailPath, exists := linkElem.Attr("href")
if !exists || title == "" {
return // 跳过无效项View on GitHub (pinned to beaa561337)