{"record":{"id":"951f2c2d2824e25e","repo":"fish2018/pansou","slug":"s-token-html-w","errorCode":null,"errorMessage":"[%s] 解析token页面HTML失败: %w","messagePattern":"\\[(.+?)\\] 解析token页面HTML失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/xys/xys.go","lineNumber":174,"sourceCode":"\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\", BaseURL+\"/\")\n\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"[%s] token请求失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != 200 {\n\t\treturn \"\", fmt.Errorf(\"[%s] token请求HTTP状态错误: %d\", p.Name(), resp.StatusCode)\n\t}\n\n\t// 解析HTML提取token\n\tdoc, err := goquery.NewDocumentFromReader(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"[%s] 解析token页面HTML失败: %w\", p.Name(), err)\n\t}\n\n\t// 查找script标签中的DToken定义\n\tvar token string\n\tdoc.Find(\"script\").Each(func(i int, s *goquery.Selection) {\n\t\tscriptContent := s.Text()\n\t\tif strings.Contains(scriptContent, \"DToken\") {\n\t\t\t// 使用正则表达式提取token\n\t\t\tre := regexp.MustCompile(`const\\s+DToken\\s*=\\s*\"([^\"]+)\"`)\n\t\t\tmatches := re.FindStringSubmatch(scriptContent)\n\t\t\tif len(matches) > 1 {\n\t\t\t\ttoken = matches[1]\n\t\t\t\tif p.debugMode {\n\t\t\t\t\tlog.Printf(\"[XYS] 从script中提取到token: %s\", token[:10]+\"...\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/xys/xys.go#L156-L192","documentation":"getToken wraps the error from goquery.NewDocumentFromReader when the token page body cannot be parsed as HTML. Since the body was already streamed from resp.Body, this usually indicates the response was truncated, empty, or binary/compressed content that goquery (html.Parse) cannot handle.","triggerScenarios":"goquery.NewDocumentFromReader(resp.Body) returns err — malformed/truncated HTML, empty body after a 200 response, or non-HTML content (gzip not decompressed, binary data) on the token page.","commonSituations":"Anti-bot interstitial serving broken HTML with status 200; proxy mangling the response; server returning compressed body without the client transparently decompressing it; Content-Sniffing mismatch.","solutions":["Capture the raw body first (io.ReadAll) and check it is non-empty and looks like HTML before parsing","Ensure the http.Client Transport has DecompressBody/Accept-Encoding handled (DisableCompression=false) so gzip bodies are decoded","Log a body prefix on parse failure to see what the server returned","If the site changed its page structure, verify the token page is still HTML and update scraping accordingly"],"exampleFix":"// before\ndoc, err := goquery.NewDocumentFromReader(resp.Body)\n// after\nraw, rerr := io.ReadAll(resp.Body)\nif rerr != nil {\n    return \"\", fmt.Errorf(\"[%s] 读取token页面失败: %w\", p.Name(), rerr)\n}\ndoc, err := goquery.NewDocumentFromReader(bytes.NewReader(raw))","handlingStrategy":"validation","validationCode":"raw, _ := io.ReadAll(resp.Body)\nif len(raw) == 0 || !bytes.Contains(bytes.ToLower(raw[:min(512, len(raw))]), []byte(\"<\")) {\n    return fmt.Errorf(\"response is not HTML\")\n}","typeGuard":null,"tryCatchPattern":"doc, err := goquery.NewDocumentFromReader(bytes.NewReader(raw))\nif err != nil {\n    log.Printf(\"token page HTML parse failed (%d bytes): %q\", len(raw), raw[:min(200, len(raw))])\n    return errTokenPageUnparseable\n}","preventionTips":["Read the full body first and parse from memory so you can log it on failure","Ensure Transport decompression is enabled so gzip bodies are handled","Check Content-Type header before parsing as HTML"],"tags":["html","parsing","goquery"],"backgroundTag":"html-parse-failed","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"}