{"record":{"id":"1c1fb1420a30eeec","repo":"fish2018/pansou","slug":"error-1c1fb1","errorCode":null,"errorMessage":"首页未找到入口脚本","messagePattern":"首页未找到入口脚本","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/xiaokupan/xiaokupan.go","lineNumber":238,"sourceCode":"func (p *XiaokupanPlugin) discoverServerFunctionID(client *http.Client) (string, error) {\n\tctx, cancel := context.WithTimeout(context.Background(), requestTimeout)\n\tdefer cancel()\n\n\thomeURL := strings.TrimRight(p.baseURL, \"/\") + \"/\"\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, homeURL, nil)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36\")\n\treq.Header.Set(\"Accept\", \"text/html,application/xhtml+xml\")\n\thomeBody, err := doLimitedRequest(client, req, maxDiscoveryBodySize)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"读取首页失败: %w\", err)\n\t}\n\n\tassetPath := string(indexAssetPattern.Find(homeBody))\n\tif assetPath == \"\" {\n\t\treturn \"\", fmt.Errorf(\"首页未找到入口脚本\")\n\t}\n\tassetReq, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.TrimRight(p.baseURL, \"/\")+assetPath, nil)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tassetReq.Header.Set(\"User-Agent\", req.Header.Get(\"User-Agent\"))\n\tassetReq.Header.Set(\"Referer\", homeURL)\n\tassetBody, err := doLimitedRequest(client, assetReq, maxDiscoveryBodySize)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"读取入口脚本失败: %w\", err)\n\t}\n\n\trouteIndex := strings.Index(string(assetBody), \"/s/$query\")\n\tif routeIndex < 0 {\n\t\treturn \"\", fmt.Errorf(\"入口脚本未找到搜索路由\")\n\t}\n\twindowStart := max(0, routeIndex-2048)\n\thashes := hashPattern.FindAll(assetBody[windowStart:routeIndex], -1)","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/xiaokupan/xiaokupan.go#L220-L256","documentation":"discoverServerFunctionID fetches the Xiaokupan site homepage and regex-extracts the JS entry-bundle path via indexAssetPattern. If the pattern does not match anything in the HTML, it returns this error instead of continuing, because the next step (fetching the entry script) cannot proceed without a path. It is thrown when the site's homepage markup no longer matches the expected script-tag shape.","triggerScenarios":"indexAssetPattern.Find(homeBody) returns an empty match: the homepage HTML contains no <script src=...> (or equivalent) tag matching the pattern — e.g. the site returned a challenge/captcha page, an error page, a redirect stub, or changed its bundler/template output.","commonSituations":"The upstream site redesigned its frontend or changed its asset bundling; a CDN/WAF serves a bot-check page instead of the real homepage; network middleware intercepts the request; the plugin was written against an older site layout.","solutions":["Fetch the homepage manually (curl with a browser User-Agent) and compare the actual script tag against indexAssetPattern; update the regex to match the new markup.","Check whether the request was served by a WAF/anti-bot layer (inspect homeBody content) and add appropriate headers/cookies to req.","Pin/upgrade the plugin to a version that matches the current site layout.","Log homeBody on this failure path to diagnose which page shape was actually received."],"exampleFix":"// before\nassetPath := string(indexAssetPattern.Find(homeBody))\nif assetPath == \"\" {\n\treturn \"\", fmt.Errorf(\"首页未找到入口脚本\")\n}\n// after\nassetPath := string(indexAssetPattern.Find(homeBody))\nif assetPath == \"\" {\n\treturn \"\", fmt.Errorf(\"首页未找到入口脚本 (body %d bytes, first 200: %.200q)\", len(homeBody), homeBody)\n}","handlingStrategy":"fallback","validationCode":"resp, _ := http.Get(baseURL)\nbody, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20))\nif !indexAssetPattern.Match(body) {\n\t// site layout changed or blocked; skip plugin or alert\n}","typeGuard":"func hasEntryAsset(homeBody []byte) bool { return len(indexAssetPattern.Find(homeBody)) > 0 }","tryCatchPattern":"funcID, err := discoverServerFunctionID(ctx, req)\nif err != nil {\n\tif strings.Contains(err.Error(), \"首页未找到入口脚本\") {\n\t\tlog.Printf(\"xiaokupan layout changed: %v\", err)\n\t\treturn nil, errSkipPlugin\n\t}\n\treturn nil, err\n}","preventionTips":["Alert on this error so site-layout changes are noticed quickly.","Fetch the homepage with realistic browser headers to avoid WAF challenge pages.","Keep the asset regex tolerant (multiple tag shapes) rather than exact-match only."],"tags":["network","scraping","html-parsing","regex"],"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"}