{"record":{"id":"4ccf8e5853ed1fb1","repo":"fish2018/pansou","slug":"d-4ccf8e","errorCode":null,"errorMessage":"详情页返回状态码: %d","messagePattern":"详情页返回状态码: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/wuji/wuji.go","lineNumber":323,"sourceCode":"\t// 创建请求\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", detailURL, nil)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"创建详情页请求失败: %w\", err)\n\t}\n\t\n\t// 设置请求头\n\tp.setRequestHeaders(req)\n\t\n\t// 发送HTTP请求\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"详情页请求失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\t\n\t// 检查状态码\n\tif resp.StatusCode != 200 {\n\t\treturn \"\", fmt.Errorf(\"详情页返回状态码: %d\", resp.StatusCode)\n\t}\n\t\n\t// 读取响应体内容\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"读取详情页响应失败: %w\", err)\n\t}\n\t\n\t// 解析HTML\n\tdoc, err := goquery.NewDocumentFromReader(strings.NewReader(string(body)))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"详情页HTML解析失败: %w\", err)\n\t}\n\t\n\t// 提取磁力链接\n\tmagnetInput := doc.Find(\"input#input-magnet\")\n\tif magnetInput.Length() == 0 {\n\t\treturn \"\", fmt.Errorf(\"未找到磁力链接输入框\")","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/wuji/wuji.go#L305-L341","documentation":"After a successful transport round-trip, fetchMagnetLink requires HTTP 200 from the detail page. Any other status code (403 anti-bot, 404 gone page, 5xx server errors, 30x leaking through) produces this error carrying the numeric status. It signals the site responded but not with the expected magnet page content.","triggerScenarios":"The detail-page GET completed and returned a status other than 200 — e.g. 403/429 from anti-scraping or rate limiting, 404 for a deleted entry, 500/502/503 from the site, or a redirect the client did not follow.","commonSituations":"Too many concurrent enrichWithMagnetLinks requests triggering rate limiting (429); the site deploying Cloudflare/anti-bot challenges (403); search-result URLs pointing to pages removed since indexing; origin server outage (5xx).","solutions":["Log the failing status code and URL; if it is 403/429, reduce MaxConcurrency and add delays between requests.","Rotate User-Agent strings (the plugin already has a userAgents list) and consider adding cookie handling for anti-bot pages.","Treat 404 as permanent: drop the result instead of retrying.","Retry 5xx responses after a delay; they are often transient.","Verify the client follows redirects appropriately for this site, or handle 30x explicitly."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"magnet, err := p.fetchMagnetLink(client, detailURL)\nvar statusErr error\nif err != nil && strings.Contains(err.Error(), \"详情页返回状态码\") {\n    log.Printf(\"non-200 detail page (%s), will back off\", detailURL)\n    time.Sleep(2 * time.Second)\n}","preventionTips":["Throttle concurrency (MaxConcurrency) to avoid 429/403 rate limiting","Rotate User-Agent strings and reuse cookies/sessions","Treat 404 as permanent skip, retry only 5xx","Log status codes to spot anti-bot deployments early"],"tags":["http","scraping","status-code","rate-limit"],"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"}