{"record":{"id":"e6a07c85a076eaa4","repo":"fish2018/pansou","slug":"s-w-e6a07c","errorCode":null,"errorMessage":"[%s] 解析搜索页面失败: %w","messagePattern":"\\[(.+?)\\] 解析搜索页面失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/djgou/djgou.go","lineNumber":156,"sourceCode":"\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}\n\t\t\tchallengeReq, reqErr := http.NewRequestWithContext(ctx, http.MethodGet, challengeURL, nil)\n\t\t\tif reqErr == nil {\n\t\t\t\tchallengeReq.Header = req.Header.Clone()\n\t\t\t\tchallengeResp, doErr := p.doRequestWithRetry(challengeReq, client)\n\t\t\t\tif doErr == nil {\n\t\t\t\t\tchallengeBody, readErr := io.ReadAll(challengeResp.Body)\n\t\t\t\t\tchallengeResp.Body.Close()\n\t\t\t\t\tif readErr == nil {\n\t\t\t\t\t\tdoc, _ = goquery.NewDocumentFromReader(strings.NewReader(string(challengeBody)))\n\t\t\t\t\t}\n\t\t\t\t}","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/djgou/djgou.go#L138-L174","documentation":"goquery.NewDocumentFromReader failed to parse the fetched search page as HTML in the djgou plugin. This wraps the goquery/html parse error and is thrown only when the response body cannot be tokenized into a document (e.g. empty or severely malformed content).","triggerScenarios":"goquery.NewDocumentFromReader(strings.NewReader(string(body))) returns err in searchImpl — typically empty body or binary/garbage content (gzip not decompressed, wrong charset stream).","commonSituations":"Server returns a compressed body without Content-Encoding handling; empty response after a 200; CDN serving error pages in unexpected formats.","solutions":["Inspect the raw body bytes on failure (hexdump/log prefix) to see what was actually returned","Ensure transparent decompression: check if you set Accept-Encoding manually without disabling Decompress in the Transport","Retry — if the body is empty it is often a transient server issue","If persistent, update parsing to handle the new content type"],"exampleFix":"// before\ntransport := &http.Transport{}\n// after\ntransport := &http.Transport{ DisableCompression: false } // or don't set Accept-Encoding manually","handlingStrategy":"fallback","validationCode":"body, _ := io.ReadAll(resp.Body)\nif len(bytes.TrimSpace(body)) == 0 {\n    return fmt.Errorf(\"empty body, skip parse\")\n}","typeGuard":null,"tryCatchPattern":"doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(body)))\nif err != nil {\n    log.Printf(\"unparseable body (%d bytes): %q\", len(body), body[:min(200,len(body))])\n    return fallbackResult()\n}","preventionTips":["Log body prefixes on parse failure to diagnose content type","Do not set Accept-Encoding manually without decompression support","Treat empty 200 bodies as transient and retry","Pin goquery/html versions and test parser against saved fixtures"],"tags":["html","parsing","goquery"],"backgroundTag":"unexpected-api-response-shape","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"}