{"record":{"id":"78ff211f93d26288","repo":"iawia002/lux","slug":"zhihu-video-id-extract-failed","errorCode":null,"errorMessage":"zhihu video id extract failed","messagePattern":"zhihu video id extract failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extractors/zhihu/zhihu.go","lineNumber":44,"sourceCode":"func New() extractors.Extractor {\n\treturn &extractor{}\n}\n\nfunc (e *extractor) Extract(url string, option extractors.Options) ([]*extractors.Data, error) {\n\tif !strings.Contains(url, videoURL) {\n\t\treturn nil, errors.WithStack(extractors.ErrURLParseFailed)\n\t}\n\n\thtml, err := request.Get(url, url, nil)\n\tif err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\n\tvideoID := utils.MatchOneOf(html, `\"videoId\":\"(\\d+)\"`)\n\ttitleMatch := utils.MatchOneOf(html, `<title.*?>(.*?)</title>`)\n\n\tif len(videoID) <= 1 {\n\t\treturn nil, errors.New(\"zhihu video id extract failed\")\n\t}\n\n\ttitle := \"Unknown\"\n\tif len(titleMatch) > 1 {\n\t\ttitle = titleMatch[1]\n\t}\n\n\tresp, err := request.GetByte(fmt.Sprintf(\"%s%s\", api, videoID[1]), url, nil)\n\tif err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\tvar data video\n\tif err = json.Unmarshal(resp, &data); err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\n\tstreams := make(map[string]*extractors.Stream)\n\tresolutions := map[string]resolution{","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/iawia002/lux/blob/dd00f6d258d80b6684a0b9402d7124e5c18ef42f/extractors/zhihu/zhihu.go#L26-L62","documentation":"The Zhihu extractor fetches the answer/article page and searches the HTML for `\"videoId\":\"(\\d+)\"` — the server-rendered embed of the player's video id. When that pattern yields one or zero captures, no video id could be found and extraction stops before the API call. Either the page has no video, or its markup no longer carries the id in that shape.","triggerScenarios":"URL points to a text-only answer or article (no video embedded); Zhihu changed its SSR data shape so the videoId key is absent/renamed; the page served to the extractor is a login wall or anti-crawler stub without player data.","commonSituations":"Scripts feeding arbitrary zhihu.com answer URLs to the downloader; content requiring login; markup drift after Zhihu front-end updates.","solutions":["Confirm the page actually contains a video by opening it in a browser","If it does contain one, fetch the same URL with the extractor's headers and grep the HTML for videoId to see whether markup changed, then update the regex in extractors/zhihu/zhihu.go","Pass a logged-in cookie if the content sits behind a login wall","Filter input URLs to known video answers before batch runs"],"exampleFix":"// before\nvideoID := utils.MatchOneOf(html, `\"videoId\":\"(\\d+)\"`)\nif len(videoID) <= 1 {\n    return nil, errors.New(\"zhihu video id extract failed\")\n}\n\n// after (diagnose whether it is 'no video' vs 'markup changed')\nvideoID := utils.MatchOneOf(html, `\"videoId\":\"(\\d+)\"`)\nif len(videoID) <= 1 {\n    if strings.Contains(html, \"videoId\") {\n        return nil, errors.New(\"zhihu video id extract failed: markup changed, videoId key present but pattern mismatched\")\n    }\n    return nil, errors.New(\"zhihu video id extract failed: page contains no video\")\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, err := zhihu.Extract(url, opts)\nif err != nil && strings.Contains(err.Error(), \"zhihu video id extract failed\") {\n    // page had no embedded videoId: text-only answer, login wall, or markup change\n    // verify in a browser; pass a login cookie if content is gated; else skip\n}","preventionTips":["Only queue zhihu URLs known to contain videos","Pass a logged-in cookie for gated content before extraction","Re-check the \"videoId\" markup pattern whenever Zhihu ships front-end changes"],"tags":["zhihu","html-parsing","login-wall","site-layout-change"],"backgroundTag":null,"analyzedSha":"dd00f6d258d80b6684a0b9402d7124e5c18ef42f","analyzedAt":"2026-08-15T16:57:31.080Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}