{"record":{"id":"38c2c0a8430f160d","repo":"fish2018/pansou","slug":"s-w-38c2c0","errorCode":null,"errorMessage":"[%s] 搜索验证失败: %w","messagePattern":"\\[(.+?)\\] 搜索验证失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/qiwei/qiwei.go","lineNumber":197,"sourceCode":"\t\t}\n\t\tlastErr = err\n\t}\n\n\tif lastErr == nil {\n\t\tlastErr = fmt.Errorf(\"[%s] 所有域名均不可用\", p.Name())\n\t}\n\treturn nil, \"\", lastErr\n}\n\nfunc (p *QiweiPlugin) searchSuggest(client *http.Client, host, keyword string) ([]suggestItem, error) {\n\tsearchURL := fmt.Sprintf(\"%s/index.php/ajax/suggest?mid=1&limit=%d&wd=%s\", host, searchSuggestLimit, url.QueryEscape(keyword))\n\tbody, err := p.fetchBody(client, searchURL, host+\"/\", searchTimeout)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif isVerifyPage(body) {\n\t\tif err := p.solveVerification(client, searchURL, body); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"[%s] 搜索验证失败: %w\", p.Name(), err)\n\t\t}\n\t\tbody, err = p.fetchBody(client, searchURL, host+\"/\", searchTimeout)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif isVerifyPage(body) {\n\t\t\treturn nil, fmt.Errorf(\"[%s] 命中验证页: %s\", p.Name(), host)\n\t\t}\n\t}\n\n\tvar resp suggestResponse\n\tif err := json.Unmarshal([]byte(body), &resp); err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] suggest 响应解析失败: %w\", p.Name(), err)\n\t}\n\n\tif resp.Code != 1 && len(resp.List) == 0 {\n\t\treturn nil, fmt.Errorf(\"[%s] suggest 响应异常: host=%s code=%d msg=%s\", p.Name(), host, resp.Code, resp.Msg)\n\t}","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/qiwei/qiwei.go#L179-L215","documentation":"Raised in searchSuggest (plugin/qiwei/qiwei.go:197) when the suggest endpoint returns an anti-bot verification page, the plugin attempts automatic verification via solveVerification, and that attempt fails. The underlying solver error is wrapped with %w so the root cause (regex mismatch, failed POST, cookie rejection) is preserved. The plugin then aborts this host, letting searchSuggestWithFallback try the next mirror.","triggerScenarios":"isVerifyPage(body) is true for the first fetchBody of /index.php/ajax/suggest (detected by the huadong verification-script regexes), and solveVerification cannot complete the challenge — e.g. the page HTML does not match verificationKeyRegex/verificationValueRegex/verificationEndpointRegex, or the verification POST fails.","commonSituations":"The site upgraded its anti-bot JS so the plugin's hardcoded regexes no longer match; the server IP is flagged and issued hard challenges; request bursts from enrichResults trip rate limiting into permanent verification mode.","solutions":["Inspect the wrapped cause (%w chain) to see whether it was HTTP failure or regex/non-match failure in solveVerification.","Fetch the page manually and compare against the verificationScriptRegex/key/value/endpoint regexes; update them if the site changed its challenge page.","Slow down request rate or add a proxy so the IP is not persistently challenged.","Wait for cooldown — verification usually clears once the cookie jar gets a valid session; consider clearing cookies/restarting."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before searching, detect a verification page early\nfunc looksLikeVerifyPage(body string) bool {\n    return strings.Contains(body, \"_yanzheng_huadong\") || strings.Contains(body, \"huadong_\")\n}","typeGuard":null,"tryCatchPattern":"items, err := p.searchSuggest(client, host, keyword)\nif err != nil && strings.Contains(err.Error(), \"搜索验证失败\") {\n    time.Sleep(2 * time.Second) // back off, then try next mirror\n    continue\n}","preventionTips":["Keep request rates modest; bursts trip the site's anti-bot and produce verification pages","Use a stable egress IP; flagged IPs get hard challenges solveVerification can't clear","Watch for site challenge-page changes and update the verification regexes promptly"],"tags":["anti-bot","captcha","verification","scraping"],"backgroundTag":"http-error-response","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}