{"record":{"id":"bf83a5d4da54adb9","repo":"fish2018/pansou","slug":"html-w-bf83a5","errorCode":null,"errorMessage":"解析HTML失败: %w","messagePattern":"解析HTML失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/leijing/leijing.go","lineNumber":149,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"发送搜索请求失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\t\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"搜索响应状态码异常: %d\", resp.StatusCode)\n\t}\n\t\n\t// 处理响应体（可能是gzip压缩的）\n\treader, err := p.getResponseReader(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t\n\t// 解析HTML\n\tdoc, err := goquery.NewDocumentFromReader(reader)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"解析HTML失败: %w\", err)\n\t}\n\t\n\t// 提取搜索结果\n\tresults := p.extractSearchResults(doc, keyword)\n\t\n\tif p.debugMode {\n\t\tlog.Printf(\"[Leijing] 找到 %d 个搜索结果\", len(results))\n\t}\n\t\n\t// 对于没有直接提取到链接的结果，访问详情页获取链接\n\tresults = p.enrichWithDetailLinks(client, results, keyword)\n\t\n\t// 过滤结果（去掉没有链接的）\n\tfilteredResults := p.filterValidResults(results)\n\t\n\tif p.debugMode {\n\t\tlog.Printf(\"[Leijing] 过滤后剩余 %d 个有效结果\", len(filteredResults))\n\t}","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/leijing/leijing.go#L131-L167","documentation":"searchImpl wraps errors from goquery.NewDocumentFromReader with this message. goquery parses the decompressed response body as HTML; this fails if the reader yields non-HTML or malformed content (JSON error page, binary data, truncated body).","triggerScenarios":"goquery.NewDocumentFromReader(reader) returns an error because the response body (after optional gzip decoding via getResponseReader) is not parseable HTML — e.g. the site returned a JSON error, an empty/chunked-corrupt body, or mis-decoded gzip output.","commonSituations":"Content-Encoding handling mismatch so gzipped bytes are parsed as HTML after a failed/incomplete gunzip; WAF returns an error page in JSON; upstream serves a captcha or binary challenge; body truncated by a proxy.","solutions":["Dump the first bytes of the response body (and Content-Type header) to see what was actually received","Verify getResponseReader handled Content-Encoding correctly (gzip vs br vs identity)","Check whether the site now returns JSON/captcha and update the plugin's parsing or headers","Bypass any proxy that could truncate or modify the body","Add a Content-Type check before parsing and skip non-HTML responses gracefully"],"exampleFix":"// before\ndoc, err := goquery.NewDocumentFromReader(reader)\nif err != nil {\n    return nil, fmt.Errorf(\"解析HTML失败: %w\", err)\n}\n// after\nct := resp.Header.Get(\"Content-Type\")\nif !strings.Contains(ct, \"text/html\") {\n    return nil, fmt.Errorf(\"unexpected content type %q\", ct)\n}\ndoc, err := goquery.NewDocumentFromReader(reader)\nif err != nil {\n    return nil, fmt.Errorf(\"解析HTML失败: %w\", err)\n}","handlingStrategy":"validation","validationCode":"ct := resp.Header.Get(\"Content-Type\")\nif !strings.Contains(ct, \"text/html\") {\n    return nil, fmt.Errorf(\"expected HTML, got %q\", ct)\n}","typeGuard":null,"tryCatchPattern":"doc, err := parseSearchHTML(reader)\nif err != nil {\n    if strings.Contains(err.Error(), \"解析HTML失败\") {\n        // dump body preview and skip this mirror for this query\n        log.Printf(\"leijing returned unparseable body: %v\", err)\n        return nil, errSkipMirror\n    }\n    return err\n}","preventionTips":["Check Content-Type before parsing HTML","Ensure gzip/brotli decoding matches the Content-Encoding header","Verify the site hasn't switched to JSON/captcha responses","Keep goquery and encoding handling up to date","Fall back to other plugins when one mirror returns garbage"],"tags":["go","html-parsing","goquery","scraping"],"backgroundTag":"unexpected-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"}