{"record":{"id":"526c2b2cab04e1eb","repo":"fish2018/pansou","slug":"s-s-526c2b","errorCode":null,"errorMessage":"[%s] 命中验证页: %s","messagePattern":"\\[(.+?)\\] 命中验证页: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/qiwei/qiwei.go","lineNumber":204,"sourceCode":"\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}\n\n\treturn resp.List, nil\n}\n\nfunc (p *QiweiPlugin) enrichResults(client *http.Client, host string, items []suggestItem, forceRefresh bool) []model.SearchResult {\n\tresults := make([]model.SearchResult, len(items))\n\tvar wg sync.WaitGroup","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/qiwei/qiwei.go#L186-L222","documentation":"Raised in searchSuggest (plugin/qiwei/qiwei.go:204) when the body is detected as a verification page, solveVerification runs and claims success, but a re-fetch of the suggest URL still yields a verification page. It means the automatic verification did not actually clear the challenge; the plugin gives up on this host and the fallback loop tries the next mirror.","triggerScenarios":"First fetch returns a verify page -> solveVerification succeeds -> second fetchBody for the same searchURL again matches isVerifyPage. Exact condition: isVerifyPage(body) true on the post-solve refetch.","commonSituations":"The site invalidates the verification cookie immediately (challenge loop); solveVerification computed the key/value but the site requires additional JS steps (fingerprinting) the plugin cannot emulate; the IP is hard-flagged so every request re-challenges regardless of cookies.","solutions":["Verify manually whether the challenge is solvable (curl the verification endpoint with the same cookie jar flow); if it loops, the IP is flagged — switch egress IP/proxy.","Update the verification regexes/endpoint handling in qiwei.go if the challenge page format changed so solveVerification silently does the wrong POST.","Reduce concurrency/request rate; enrichResults fires up to 12 concurrent detail requests which can trigger aggressive re-challenging.","Rely on fallback: ensure at least one mirror is clean; also consider clearing the plugin's cookie jar so a fresh session is used."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// after solving, verify the refetched body is really clean before parsing\nif looksLikeVerifyPage(body) {\n    return fmt.Errorf(\"verification loop on %s, switch host\", host)\n}","typeGuard":null,"tryCatchPattern":"items, host, err := p.searchSuggestWithFallback(client, keyword)\nif err != nil {\n    log.Printf(\"qiwei verification loop / host failure: %v\", err)\n    return p.searchViaOtherPlugin(keyword) // or return empty results gracefully\n}","preventionTips":["Rotate egress IP/proxy when challenges start looping — cookies alone won't fix a flagged IP","Cap concurrent detail requests (maxConcurrent) to avoid re-triggering the challenge system","Clear the cookie jar if a session is stuck in verification mode"],"tags":["anti-bot","captcha","verification-loop","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"}