{"record":{"id":"9de9d8e330767de5","repo":"iawia002/lux","slug":"error-9de9d8","errorCode":null,"errorMessage":"获取视频信息失败。","messagePattern":"获取视频信息失败。","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extractors/miaopai/miaopai.go","lineNumber":71,"sourceCode":"\tif ids == nil || len(ids) < 2 {\n\t\treturn nil, errors.WithStack(extractors.ErrURLParseFailed)\n\t}\n\tid := ids[1]\n\n\trandomString := getRandomString(10)\n\n\tvar data miaopaiData\n\tjsonString, err := request.Get(\n\t\tfmt.Sprintf(\"https://n.miaopai.com/api/aj_media/info.json?smid=%s&appid=530&_cb=_jsonp%s\", id, randomString),\n\t\turl, nil,\n\t)\n\tif err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\n\tmatch := utils.MatchOneOf(jsonString, randomString+`\\((.*)\\);$`)\n\tif match == nil || len(match) < 2 {\n\t\treturn nil, errors.New(\"获取视频信息失败。\")\n\t}\n\n\terr = json.Unmarshal([]byte(match[1]), &data)\n\tif err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\n\trealURL := data.Data.MetaData[0].URLs.M\n\tsize, err := request.Size(realURL, url)\n\tif err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\turlData := &extractors.Part{\n\t\tURL:  realURL,\n\t\tSize: size,\n\t\tExt:  \"mp4\",\n\t}\n\tstreams := map[string]*extractors.Stream{","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/iawia002/lux/blob/dd00f6d258d80b6684a0b9402d7124e5c18ef42f/extractors/miaopai/miaopai.go#L53-L89","documentation":"The miaopai extractor calls the aj_media/info.json endpoint with a random _cb callback and expects the JSONP wrapper <random>(...);. This error means the response did not match that wrapper — the API answered with an error body, empty output, or a changed format. The HTTP fetch itself succeeded.","triggerScenarios":"Deleted or private videos where the API returns an error object without the JSONP wrapper; a wrong smid; rate limiting; the endpoint moving off JSONP.","commonSituations":"Old links circulating in bookmarks or playlists; scraping bursts; miaopai API changes.","solutions":["Open the API URL (with the _cb parameter) in a browser and inspect the raw response for your smid.","Confirm the video page still exists.","If the endpoint changed shape, strip any optional wrapper and parse the JSON directly."],"exampleFix":"// before\nmatch := utils.MatchOneOf(jsonString, randomString+`\\((.*)\\);$`)\n// after — strip an optional JSONP wrapper, then unmarshal directly\nbody := strings.TrimSpace(jsonString)\nif i := strings.IndexByte(body, '('); i >= 0 {\n\tbody = strings.TrimSuffix(body[i+1:], \");\")\n}\nerr = json.Unmarshal([]byte(body), &data)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isMiaopaiInfoFailed(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"获取视频信息失败\")\n}","tryCatchPattern":"Catch per-URL, mark the smid as unavailable (deleted/private videos never recover), and continue the batch. Optionally fetch the API URL manually once to confirm whether the response is a non-JSONP error object.","preventionTips":["Treat miaopai links as perishable when archiving","Rate-limit requests to the info.json endpoint","Log the raw API response on failure to distinguish deleted videos from format changes"],"tags":["miaopai","jsonp","api","scraping"],"backgroundTag":null,"analyzedSha":"dd00f6d258d80b6684a0b9402d7124e5c18ef42f","analyzedAt":"2026-08-15T16:57:31.080Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}