{"record":{"id":"155f5273db287466","repo":"fish2018/pansou","slug":"s-html-w","errorCode":null,"errorMessage":"[%s] 解析HTML失败: %w","messagePattern":"\\[(.+?)\\] 解析HTML失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/aikanzy/aikanzy.go","lineNumber":174,"sourceCode":"\treq.Header.Set(\"Upgrade-Insecure-Requests\", \"1\")\n\treq.Header.Set(\"Cache-Control\", \"max-age=0\")\n\t\n\t// 使用带重试的请求方法发送HTTP请求\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\t// 检查状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"[%s] 请求搜索页面失败，状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\t\n\t// 使用goquery解析HTML\n\tdoc, err := goquery.NewDocumentFromReader(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 解析HTML失败: %w\", p.Name(), err)\n\t}\n\t\n\t// 解析搜索结果列表\n\tarticleItems := p.parseArticleList(doc)\n\tif len(articleItems) == 0 {\n\t\treturn []model.SearchResult{}, nil\n\t}\n\t\n\t// 并发抓取详情页获取网盘链接\n\tresults := p.fetchDetailsWithLinks(articleItems, client, keyword)\n\t\n\t// 使用过滤功能过滤结果\n\tfilteredResults := plugin.FilterResultsByKeyword(results, keyword)\n\t\n\treturn filteredResults, nil\n}\n\n// ArticleItem 文章基本信息","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/aikanzy/aikanzy.go#L156-L192","documentation":"Returned by doSearch in the aikanzy plugin when goquery.NewDocumentFromReader fails to parse the HTTP response body as HTML. This is rare — it occurs only when reading the body fails (I/O error) or the response body is not valid parseable content (e.g. binary data, compressed/garbled encoding).","triggerScenarios":"After a 200 response, goquery.NewDocumentFromReader(resp.Body) returns an error because the body stream failed mid-read or the content is not HTML (e.g. a compressed body with mismatched Content-Encoding, or a challenge page served as non-HTML).","commonSituations":"Server returns gzip/brotli content that http.Client didn't transparently decompress (custom Transport missing Accept-Encoding handling); truncated response due to connection reset mid-body; site serves a CAPTCHA/JS-challenge page with unexpected encoding.","solutions":["Check that the http.Client Transport isn't forcing an Accept-Encoding the client can't decode; let net/http handle gzip automatically.","Read the body into memory first (io.ReadAll) and inspect it to confirm it is HTML before parsing.","Verify the connection isn't truncated (check for partial results; retry on read errors).","If the site serves non-HTML challenge pages, update headers/cookies to pass anti-bot checks."],"exampleFix":"// before\ndoc, err := goquery.NewDocumentFromReader(resp.Body)\nif err != nil {\n\treturn nil, fmt.Errorf(\"[%s] 解析HTML失败: %w\", p.Name(), err)\n}\n// after\nbodyBytes, err := io.ReadAll(resp.Body)\nif err != nil {\n\treturn nil, fmt.Errorf(\"[%s] 读取响应体失败: %w\", p.Name(), err)\n}\ndoc, err := goquery.NewDocumentFromReader(bytes.NewReader(bodyBytes))\nif err != nil {\n\treturn nil, fmt.Errorf(\"[%s] 解析HTML失败 (前100字节: %q): %w\", p.Name(), bodyBytes[:min(100, len(bodyBytes))], err)\n}","handlingStrategy":"try-catch","validationCode":"ct := resp.Header.Get(\"Content-Type\")\nif !strings.Contains(ct, \"text/html\") {\n\treturn fmt.Errorf(\"unexpected content type: %s\", ct)\n}","typeGuard":null,"tryCatchPattern":"doc, err := goquery.NewDocumentFromReader(resp.Body)\nif err != nil {\n\t// retry once; if it persists, dump the body for inspection\n\traw, rerr := io.ReadAll(resp.Body)\n\tif rerr == nil {\n\t\tlog.Printf(\"unparseable body head: %q\", raw[:min(200, len(raw))])\n\t}\n\treturn err\n}","preventionTips":["Let net/http handle gzip/deflate transparently; don't set Accept-Encoding manually unless you decode it yourself.","Verify Content-Type is text/html before parsing.","Read the full body with a size limit and check for truncation.","Treat CAPTCHA/challenge responses as an anti-bot signal, not a parse bug."],"tags":["html-parsing","goquery","scraping","go"],"backgroundTag":"invalid-json-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"}