{"record":{"id":"c6b5889db6f4f4fc","repo":"fish2018/pansou","slug":"s-d-c6b588","errorCode":null,"errorMessage":"[%s] 搜索请求返回状态码: %d","messagePattern":"\\[(.+?)\\] 搜索请求返回状态码: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/djgou/djgou.go","lineNumber":145,"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/114.0.0.0 Safari/537.36\")\n\treq.Header.Set(\"Accept\", \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;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\", SiteURL)\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\n\tif resp.StatusCode != 200 {\n\t\tresp.Body.Close()\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求返回状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\n\t// 6. 读取并解析搜索结果页面。部分节点先返回 BTWAF JS 跳转页。\n\tbody, err := io.ReadAll(resp.Body)\n\tresp.Body.Close()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 读取搜索页面失败: %w\", p.Name(), err)\n\t}\n\tdoc, err := goquery.NewDocumentFromReader(strings.NewReader(string(body)))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 解析搜索页面失败: %w\", p.Name(), err)\n\t}\n\tif doc.Find(\"article.post-item-row\").Length() == 0 {\n\t\tif match := btwafURLRegex.FindStringSubmatch(string(body)); len(match) > 1 {\n\t\t\tchallengeURL := match[1]\n\t\t\tif strings.HasPrefix(challengeURL, \"/\") {\n\t\t\t\tchallengeURL = SiteURL + challengeURL\n\t\t\t}","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/djgou/djgou.go#L127-L163","documentation":"The djgou plugin returns this when the search HTTP response status code is not 200. The library treats any non-200 (403, 429, 5xx, redirects to challenge pages) as a failed search because it expects an HTML results page. The response body is closed and the code is reported.","triggerScenarios":"searchImpl received a valid HTTP response but resp.StatusCode != 200 — e.g. anti-bot 403, rate-limit 429, 5xx from the origin, or an unexpected redirect target.","commonSituations":"Site behind WAF blocking datacenter IPs; request rate too high; missing/expired cookies or headers; site moved and now redirects to a page the client does not follow to a 200.","solutions":["Log the status code and compare against recent site behavior (403=blocked, 429=rate limited, 5xx=server-side)","Slow down request rate / add jitter and respect backoff","Verify headers (Referer, User-Agent, Cache-Control) still match what a browser sends","If the site now redirects or challenges, update SiteURL/cookie handling in the plugin"],"exampleFix":"// before\nif err != nil { return err } // generic handling\n// after\nvar se *ErrSearchStatus\nif errors.As(err, &se) && se.Code == 429 {\n    time.Sleep(30 * time.Second)\n    items, err = p.searchImpl(keyword)\n}","handlingStrategy":"try-catch","validationCode":"resp, err := client.Head(siteURL)\nif err == nil && resp.StatusCode != 200 {\n    log.Printf(\"site currently returns %d, expecting blocking\", resp.StatusCode)\n}\nif resp != nil { resp.Body.Close() }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"搜索返回状态码\") {\n    code := extractStatusCode(err) // parse from message\n    switch code {\n    case 429: time.Sleep(time.Minute); retry()\n    case 403: rotateHeadersOrIP(); retry()\n    default: giveUp()\n    }\n}","preventionTips":["Keep Referer/User-Agent headers identical to a real browser","Rate-limit requests to the site","Handle 403/429 with distinct backoff policies","Re-verify site status manually before assuming a bug"],"tags":["http","http-status","search"],"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"}