{"record":{"id":"8b394cb216b981c7","repo":"fish2018/pansou","slug":"s-d-8b394c","errorCode":null,"errorMessage":"[%s] 搜索请求返回状态码: %d","messagePattern":"\\[(.+?)\\] 搜索请求返回状态码: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/labi/labi.go","lineNumber":204,"sourceCode":"\n\t// 4. 设置完整的请求头（避免反爬虫）\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(\"Upgrade-Insecure-Requests\", \"1\")\n\treq.Header.Set(\"Cache-Control\", \"max-age=0\")\n\treq.Header.Set(\"Referer\", strings.TrimRight(baseURL, \"/\")+\"/\")\n\n\t// 5. 发送请求（带重试机制）\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\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求返回状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\n\t// 3. 解析搜索结果页面\n\tdoc, err := goquery.NewDocumentFromReader(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 解析搜索页面失败: %w\", p.Name(), err)\n\t}\n\n\t// 4. 提取搜索结果\n\tvar results []model.SearchResult\n\n\tdoc.Find(\".module-search-item\").Each(func(i int, s *goquery.Selection) {\n\t\tresult := p.parseSearchItem(s, keyword)\n\t\tif result.UniqueID != \"\" {\n\t\t\tresults = append(results, result)\n\t\t}\n\t})\n","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/labi/labi.go#L186-L222","documentation":"searchAtBase rejects any labi mirror response whose HTTP status is not 200. The fetch succeeded at transport level after retries, but the server answered with 403/404/5xx etc., so the plugin refuses to parse the body and fails this mirror.","triggerScenarios":"doRequestWithRetry returns a response with resp.StatusCode != 200 for the mirror's search URL — typically 403 from anti-bot WAF, 404 after a path change, or 5xx during site trouble.","commonSituations":"Cloudflare/WAF blocking the server IP (403), stale search path after a site redesign (404), rate limiting (429) under heavy scraping, mirror under maintenance (503).","solutions":["Check the numeric status in the error message: 403/429 → anti-bot/rate limit, 404 → wrong URL, 5xx → upstream outage","For anti-bot: improve headers (the code already sets browser-like UA/Accept/Referer), add cookies, or use a residential proxy","For 404: update the search URL pattern to the site's current structure","Let the caller fall back to the next mirror instead of surfacing this error directly"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"搜索请求返回状态码\") {\n        // parse the status from the message or track it upstream;\n        // 403/429 → back off or proxy, 404 → fix path, 5xx → retry later\n        return tryNextMirror(kw)\n    }\n    return err\n}","preventionTips":["Classify by status code before choosing a remedy","Rotate proxies/egress IPs when 403/429 rates climb","Monitor per-mirror status distributions to detect WAF blocks early","Refresh URL patterns after site redesigns to avoid 404s"],"tags":["http","status-code","scraping","anti-bot"],"backgroundTag":"http-non-200-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"}