{"record":{"id":"7aa5118b9256cb87","repo":"fish2018/pansou","slug":"s-d-7aa511","errorCode":null,"errorMessage":"[%s] 请求搜索页面失败，状态码: %d","messagePattern":"\\[(.+?)\\] 请求搜索页面失败，状态码: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/aikanzy/aikanzy.go","lineNumber":168,"sourceCode":"\t// 设置完整的请求头（避免反爬虫）\n\treq.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\")\n\treq.Header.Set(\"Accept\", \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\")\n\treq.Header.Set(\"Accept-Language\", \"zh-CN,zh;q=0.9,en;q=0.8\")\n\treq.Header.Set(\"Connection\", \"keep-alive\")\n\treq.Header.Set(\"Referer\", \"https://www.aikanzy.com/\")\n\treq.Header.Set(\"Upgrade-Insecure-Requests\", \"1\")\n\treq.Header.Set(\"Cache-Control\", \"max-age=0\")\n\t\n\t// 使用带重试的请求方法发送HTTP请求\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 请求搜索页面失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\t\n\t// 检查状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"[%s] 请求搜索页面失败，状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\t\n\t// 使用goquery解析HTML\n\tdoc, err := goquery.NewDocumentFromReader(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 解析HTML失败: %w\", p.Name(), err)\n\t}\n\t\n\t// 解析搜索结果列表\n\tarticleItems := p.parseArticleList(doc)\n\tif len(articleItems) == 0 {\n\t\treturn []model.SearchResult{}, nil\n\t}\n\t\n\t// 并发抓取详情页获取网盘链接\n\tresults := p.fetchDetailsWithLinks(articleItems, client, keyword)\n\t\n\t// 使用过滤功能过滤结果","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/aikanzy/aikanzy.go#L150-L186","documentation":"Returned by doSearch in the aikanzy plugin when the HTTP response status code is anything other than 200 OK. The body is not parsed; the actual status code is interpolated into the message. It signals the site responded but rejected or redirected the request (anti-bot, rate limit, moved page).","triggerScenarios":"p.doRequestWithRetry succeeds (a response was received) but resp.StatusCode != http.StatusOK — e.g. 403 from Cloudflare/anti-bot protection, 429 rate limit, 404 because the search URL path changed, or 301/302 not followed.","commonSituations":"The site enabled stricter anti-bot measures and rejects the hardcoded Chrome/91 User-Agent; search path/format changed after a site update; too many requests triggered rate limiting; the site moved to a new domain.","solutions":["Log the status code and read a snippet of resp.Body to see whether it's Cloudflare, a redirect page, or 404.","Update the User-Agent and headers to a current browser fingerprint (Chrome/91 is outdated and often blocked).","Check if the site's search URL path changed and update baseURL/path construction.","Back off and retry with jitter on 429/503 instead of hammering.","Update the plugin to the site's new domain or a mirror if the site moved."],"exampleFix":"// before\nif resp.StatusCode != http.StatusOK {\n\treturn nil, fmt.Errorf(\"[%s] 请求搜索页面失败，状态码: %d\", p.Name(), resp.StatusCode)\n}\n// after\nif resp.StatusCode != http.StatusOK {\n\tbody, _ := io.ReadAll(io.LimitReader(resp.Body, 512))\n\treturn nil, fmt.Errorf(\"[%s] 请求搜索页面失败，状态码: %d, body: %s\", p.Name(), resp.StatusCode, string(body))\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if resp.StatusCode != http.StatusOK {\n\tswitch {\n\tcase resp.StatusCode == http.StatusTooManyRequests:\n\t\t// honor Retry-After header, then retry\n\tcase resp.StatusCode == http.StatusForbidden:\n\t\t// refresh headers/cookies or rotate User-Agent\n\tdefault:\n\t\treturn fmt.Errorf(\"unexpected status %d\", resp.StatusCode)\n\t}\n}","preventionTips":["Keep the spoofed User-Agent and header set current (Chrome/91 is outdated).","Handle 3xx explicitly (CheckRedirect policy) so redirects aren't mistaken for failures.","Add rate limiting to stay under the site's thresholds.","Log status + a body snippet on every non-200 to speed diagnosis."],"tags":["http-status","anti-bot","scraping","go"],"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"}