fish2018/pansou · error
[ ] 搜索请求返回状态码
Error message
[%s] 搜索请求返回状态码: %d
What it means
The djgou plugin returns this when the search HTTP response status code is not 200. The library treats any non-200 (403, 429, 5xx, redirects to challenge pages) as a failed search because it expects an HTML results page. The response body is closed and the code is reported.
Solutions
- Log the status code and compare against recent site behavior (403=blocked, 429=rate limited, 5xx=server-side)
- Slow down request rate / add jitter and respect backoff
- Verify headers (Referer, User-Agent, Cache-Control) still match what a browser sends
- If the site now redirects or challenges, update SiteURL/cookie handling in the plugin
Example fix
// before
if err != nil { return err } // generic handling
// after
var se *ErrSearchStatus
if errors.As(err, &se) && se.Code == 429 {
time.Sleep(30 * time.Second)
items, err = p.searchImpl(keyword)
} Defensive patterns
Strategy: try-catch
Validate before calling
resp, err := client.Head(siteURL)
if err == nil && resp.StatusCode != 200 {
log.Printf("site currently returns %d, expecting blocking", resp.StatusCode)
}
if resp != nil { resp.Body.Close() } Try / catch
if err != nil && strings.Contains(err.Error(), "搜索返回状态码") {
code := extractStatusCode(err) // parse from message
switch code {
case 429: time.Sleep(time.Minute); retry()
case 403: rotateHeadersOrIP(); retry()
default: giveUp()
}
} Prevention
- Keep Referer/User-Agent headers identical to a real browser
- Rate-limit requests to the site
- Handle 403/429 with distinct backoff policies
- Re-verify site status manually before assuming a bug
When it happens
Trigger: searchImpl received a valid HTTP response but resp.StatusCode != 200 — e.g. anti-bot 403, rate-limit 429, 5xx from the origin, or an unexpected redirect target.
Common situations: Site behind WAF blocking datacenter IPs; request rate too high; missing/expired cookies or headers; site moved and now redirects to a page the client does not follow to a 200.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/c6b5889db6f4f4fc.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/djgou/djgou.go:145
// 4. 设置完整的请求头(避免反爬虫)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;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", SiteURL)
// 5. 发送请求(带重试机制)
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
if resp.StatusCode != 200 {
resp.Body.Close()
return nil, fmt.Errorf("[%s] 搜索请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// 6. 读取并解析搜索结果页面。部分节点先返回 BTWAF JS 跳转页。
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return nil, fmt.Errorf("[%s] 读取搜索页面失败: %w", p.Name(), err)
}
doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(body)))
if err != nil {
return nil, fmt.Errorf("[%s] 解析搜索页面失败: %w", p.Name(), err)
}
if doc.Find("article.post-item-row").Length() == 0 {
if match := btwafURLRegex.FindStringSubmatch(string(body)); len(match) > 1 {
challengeURL := match[1]
if strings.HasPrefix(challengeURL, "/") {
challengeURL = SiteURL + challengeURL
}View on GitHub (pinned to beaa561337)