iawia002/lux · error
zhihu video id extract failed
Error message
zhihu video id extract failed
What it means
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.
Source
Thrown at extractors/zhihu/zhihu.go:44
func New() extractors.Extractor {
return &extractor{}
}
func (e *extractor) Extract(url string, option extractors.Options) ([]*extractors.Data, error) {
if !strings.Contains(url, videoURL) {
return nil, errors.WithStack(extractors.ErrURLParseFailed)
}
html, err := request.Get(url, url, nil)
if err != nil {
return nil, errors.WithStack(err)
}
videoID := utils.MatchOneOf(html, `"videoId":"(\d+)"`)
titleMatch := utils.MatchOneOf(html, `<title.*?>(.*?)</title>`)
if len(videoID) <= 1 {
return nil, errors.New("zhihu video id extract failed")
}
title := "Unknown"
if len(titleMatch) > 1 {
title = titleMatch[1]
}
resp, err := request.GetByte(fmt.Sprintf("%s%s", api, videoID[1]), url, nil)
if err != nil {
return nil, errors.WithStack(err)
}
var data video
if err = json.Unmarshal(resp, &data); err != nil {
return nil, errors.WithStack(err)
}
streams := make(map[string]*extractors.Stream)
resolutions := map[string]resolution{View on GitHub (pinned to dd00f6d258)
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
Example fix
// before
videoID := utils.MatchOneOf(html, `"videoId":"(\d+)"`)
if len(videoID) <= 1 {
return nil, errors.New("zhihu video id extract failed")
}
// after (diagnose whether it is 'no video' vs 'markup changed')
videoID := utils.MatchOneOf(html, `"videoId":"(\d+)"`)
if len(videoID) <= 1 {
if strings.Contains(html, "videoId") {
return nil, errors.New("zhihu video id extract failed: markup changed, videoId key present but pattern mismatched")
}
return nil, errors.New("zhihu video id extract failed: page contains no video")
} Defensive patterns
Strategy: try-catch
Try / catch
_, err := zhihu.Extract(url, opts)
if err != nil && strings.Contains(err.Error(), "zhihu video id extract failed") {
// page had no embedded videoId: text-only answer, login wall, or markup change
// verify in a browser; pass a login cookie if content is gated; else skip
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Scripts feeding arbitrary zhihu.com answer URLs to the downloader; content requiring login; markup drift after Zhihu front-end updates.
Related errors
- Could not read page data
- empty list
- this page has no playlist
- could not find video in page
- ErrURLParseFailed
AI-assisted analysis of iawia002/lux@dd00f6d258 (2026-08-15).
Data as JSON: /api/errors/78ff211f93d26288.
Report an issue: GitHub.