{"record":{"id":"356629e71a1d3a53","repo":"fish2018/pansou","slug":"s-d","errorCode":null,"errorMessage":"[%s] 搜索请求返回状态码: %d","messagePattern":"\\[(.+?)\\] 搜索请求返回状态码: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/ahhhhfs/ahhhhfs.go","lineNumber":186,"sourceCode":"\t\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/120.0.0.0 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\", \"https://www.ahhhhfs.com/\")\n\t\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\t\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求返回状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\t\n\t// 6. 解析搜索结果页面\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\t\n\t// 7. 提取搜索结果\n\tvar results []model.SearchResult\n\tvar wg sync.WaitGroup\n\tvar mu sync.Mutex\n\tsemaphore := make(chan struct{}, MaxConcurrency)\n\t\n\tdoc.Find(\"article.post-item.item-list\").Each(func(i int, s *goquery.Selection) {\n\t\t// 解析基本信息\n\t\ttitleElem := s.Find(\".entry-title a\")\n\t\ttitle := strings.TrimSpace(titleElem.Text())","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/ahhhhfs/ahhhhfs.go#L168-L204","documentation":"After doRequestWithRetry succeeds, searchImpl checks resp.StatusCode != 200 and returns this formatted message with the numeric status. The site responded, but not with an OK status — for a scraped WordPress-style search on ahhhhfs.com this usually means anti-bot/WAF blocking (403), rate limiting (429), a moved path (404), or a server error (5xx).","triggerScenarios":"The GET to the ahhhhfs search URL returns 301/302 (redirect not resolved to 200), 403 (Cloudflare/WAF rejects the spoofed browser headers), 404 (search URL structure changed), 429 (too many requests), or 5xx while the site is degraded.","commonSituations":"Scraping too aggressively triggers rate limiting; the site enabled stricter bot protection that detects the hardcoded Chrome 120 User-Agent; the site changed its search path; temporary site outage (502/503).","solutions":["Log the status code and read the body on 403/503 to identify Cloudflare or captcha challenges.","Replay the request with curl using the same headers to confirm whether it's header-based blocking.","Refresh the request headers (current browser User-Agent, cookies) used to dodge anti-bot checks.","Add throttling/backoff between searches to avoid 429; retry after the Retry-After interval when present.","Update the searchURL if the site changed its search endpoint structure."],"exampleFix":"// before\nif resp.StatusCode != 200 {\n    return nil, fmt.Errorf(\"[%s] 搜索请求返回状态码: %d\", p.Name(), resp.StatusCode)\n}\n// after\nif resp.StatusCode != 200 {\n    snippet, _ := io.ReadAll(io.LimitReader(resp.Body, 512))\n    return nil, fmt.Errorf(\"[%s] 搜索请求返回状态码: %d, body: %s\", p.Name(), resp.StatusCode, snippet)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"results, err := p.Search(ctx, keyword)\nvar codeErr *statusCodeError // 若封装了状态码\nif err != nil && strings.Contains(err.Error(), \"429\") {\n    time.Sleep(retryAfter) // 遵循 Retry-After 后重试\n    results, err = p.Search(ctx, keyword)\n}","preventionTips":["Rate-limit searches and add jittered backoff to avoid 429/403.","Keep anti-bot headers (current User-Agent, cookies) fresh.","On repeated 4xx, check the site in a browser for new WAF/captcha protection.","Update the search URL when the site changes structure."],"tags":["go","http","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"}