{"record":{"id":"e2584f56bcc0fcea","repo":"fish2018/pansou","slug":"qrid","errorCode":null,"errorMessage":"无法提取qrid","messagePattern":"无法提取qrid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/weibo/weibo.go","lineNumber":1819,"sourceCode":"\t\treturn nil, \"\", err\n\t}\n\t\n\t// 响应是JSONP格式，提取JSON部分\n\tinfoText := string(infoBody)\n\t\n\t// 提取api_key: 正则 api_key=(.*)\"\n\tapiKeyRegex := regexp.MustCompile(`api_key=([^\"]+)`)\n\tapiKeyMatch := apiKeyRegex.FindStringSubmatch(infoText)\n\tif len(apiKeyMatch) < 2 {\n\t\treturn nil, \"\", fmt.Errorf(\"无法提取api_key\")\n\t}\n\tapiKey := apiKeyMatch[1]\n\t\n\t// 提取qrid: 正则 \"qrid\":\"(.*?)\"\n\tqridRegex := regexp.MustCompile(`\"qrid\":\"([^\"]+)\"`)\n\tqridMatch := qridRegex.FindStringSubmatch(infoText)\n\tif len(qridMatch) < 2 {\n\t\treturn nil, \"\", fmt.Errorf(\"无法提取qrid\")\n\t}\n\tqrid := qridMatch[1]\n\t\n\t// 第二步：使用api_key获取二维码图片\n\tqrImageURL := fmt.Sprintf(\"https://v2.qr.weibo.cn/inf/gen?api_key=%s\", apiKey)\n\t\n\tqrReq, err := http.NewRequest(\"GET\", qrImageURL, nil)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\t\n\tqrReq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36\")\n\tqrReq.Header.Set(\"Referer\", \"https://weibo.com/\")\n\t\n\tqrResp, err := client.Do(qrReq)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}","sourceCodeStart":1801,"sourceCodeEnd":1837,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/weibo/weibo.go#L1801-L1837","documentation":"Raised by generateQRCodeWithSig when the regex \"qrid\":\"([^\"]+)\" finds no qrid in the info page body. api_key extraction succeeded (error 751 did not fire), but the qrid needed to poll QR scan status is absent, so QR generation aborts. This means the endpoint response is missing the expected qrid JSON field.","triggerScenarios":"generateQRCodeWithSig (called by handleGetStatus, handleRefreshQRCode) successfully extracts api_key but qridRegex.FindStringSubmatch returns fewer than 2 groups on the same infoText.","commonSituations":"Weibo changed the response format (qrid renamed or nested differently); a partial/error response that still contains api_key but not qrid; response truncated by a proxy or size limit; endpoint serving different content per region or session state.","solutions":["Dump infoText on failure to inspect the actual response structure around qrid.","Update the qrid regex/parsing to match the current response format (e.g. accept qrid without quotes or nested JSON).","Re-request the info page with proper headers/cookies; a stale or anonymous session may get a degraded response.","Retry generation once — transient truncation or a race with session setup can omit qrid."],"exampleFix":"// before\nqridMatch := qridRegex.FindStringSubmatch(infoText)\nif len(qridMatch) < 2 {\n    return nil, \"\", fmt.Errorf(\"无法提取qrid\")\n}\n// after: accept both quoted JSON and bare forms\nqridRegex := regexp.MustCompile(`\"?qrid\"?\\s*[=:]\\s*\"?([A-Za-z0-9_-]+)`)\nqridMatch := qridRegex.FindStringSubmatch(infoText)\nif len(qridMatch) < 2 {\n    return nil, \"\", fmt.Errorf(\"无法提取qrid, 响应长度: %d\", len(infoText))\n}","handlingStrategy":"validation","validationCode":"// Go: confirm qrid is present in the body before relying on it\nif !strings.Contains(infoText, \"qrid\") {\n    return fmt.Errorf(\"info response has no qrid field (len=%d)\", len(infoText))\n}","typeGuard":"func hasQRID(infoText string) bool {\n    return regexp.MustCompile(`\"?qrid\"?\\s*[=:]\\s*\"?([A-Za-z0-9_-]+)`).MatchString(infoText)\n}","tryCatchPattern":"qr, _, err := plugin.GenerateQRCodeWithSig(...)\nif err != nil {\n    if strings.Contains(err.Error(), \"无法提取qrid\") {\n        // response shape drift; refetch once before giving up\n        return retryOrFail(err)\n    }\n    return err\n}","preventionTips":["Refetch the info page when qrid is missing; a partial or degraded response is often transient.","Make the qrid parser tolerant of both quoted-JSON and bare key=value formats.","Log the body (truncated) on extraction failure to catch Weibo format changes quickly.","Verify api_key and qrid come from the same successful response; don't mix across requests."],"tags":["weibo","qr-code","regex-scraping","unexpected-response"],"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"}