fish2018/pansou · error
机器人验证出现循环
Error message
机器人验证出现循环
What it means
Raised when, after submitting the challenge verification, the returned page is still detected as a bot-challenge page (isBotChallengePage(respBody)), meaning verification entered a loop rather than granting access. The library aborts instead of retrying forever.
Solutions
- Reuse the SAME scraper instance across challenge fetch, submit, and retry so cookies persist.
- Check that saved cookies are applied via createScraperWithCookies and session refresh is disabled.
- Update the cloudscraper dependency — challenge format may have changed.
- Rotate exit IP/proxy; datacenter IPs often get perpetual challenges.
Example fix
// before scraper := cloudscraper.New() // fresh instance per request, cookies lost // after scraper, _ := p.createScraperWithCookies(savedCookieStr) // reuse cookies + jar
Defensive patterns
Strategy: fallback
Validate before calling
if len(savedCookies) == 0 { /* re-login or fetch a fresh session before attempting challenge flow */ } Try / catch
if err := p.fetch(url); err != nil { if strings.Contains(err.Error(), "机器人验证出现循环") { scraper = p.createScraperWithCookies(freshCookies); retryOnce() } } Prevention
- Keep one scraper instance for the entire challenge flow
- Keep cookies across requests; never clear the jar mid-flow
- Keep cloudscraper up to date
- Avoid datacenter/proxy IPs known to be flagged
When it happens
Trigger: submitChallengeVerification POSTs the solved form, reads the body, and isBotChallengePage(body) is still true — the site returns another challenge page.
Common situations: Challenge cookies were not persisted (fresh scraper or cleared cookie jar), site upgraded its anti-bot (e.g. new Cloudflare turnstile), browser fingerprint/TLS signature rejected, or requests routed through IPs the site blocks (datacenter/proxy IPs).
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/60825a11c486a52e.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/gying/gying.go:1883
}
func (p *GyingPlugin) submitChallengeVerification(scraper *cloudscraper.Scraper, requestURL string, form url.Values) error {
resp, err := scraper.Post(requestURL, "application/x-www-form-urlencoded", strings.NewReader(form.Encode()))
if err != nil {
return fmt.Errorf("提交验证失败: %w", err)
}
defer resp.Body.Close()
if DebugLog {
fmt.Printf("[Gying] Challenge提交完成: url=%s status=%d\n", requestURL, resp.StatusCode)
}
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("读取验证响应失败: %w", err)
}
if isBotChallengePage(respBody) {
return fmt.Errorf("机器人验证出现循环")
}
var verifyResp challengeVerifyResponse
if err := json.Unmarshal(respBody, &verifyResp); err != nil {
return fmt.Errorf("解析验证响应失败: %w", err)
}
if !verifyResp.Success {
if verifyResp.Msg != "" {
return fmt.Errorf("机器人验证失败: %s", verifyResp.Msg)
}
return fmt.Errorf("机器人验证失败")
}
if DebugLog {
fmt.Printf("[Gying] Challenge验证成功: url=%s\n", requestURL)
}
return nilView on GitHub (pinned to beaa561337)