fish2018/pansou · error
无法提取api_key
Error message
无法提取api_key
What it means
Raised by generateQRCodeWithSig when the regex api_key=([^"]+) fails to find an api_key value in the HTML/text body fetched from the Weibo QR info endpoint. The plugin scrapes api_key and qrid out of the response to build the QR generation URL; if the page doesn't contain the expected pattern, this error stops QR-code generation. It indicates the response body didn't match the scraped format.
Solutions
- Log the raw infoText on failure to see what the endpoint actually returned.
- Re-fetch — transient blocks/captchas often clear; add proper headers (User-Agent, Referer) so the endpoint serves the real page.
- Check whether Weibo changed the page and update the api_key regex to match the new format (e.g. JSON key "api_key":"...").
- Verify the info request itself succeeded (check HTTP status/body length before regex matching) and fail earlier with a clearer message if not.
Example fix
// before
apiKeyMatch := apiKeyRegex.FindStringSubmatch(infoText)
if len(apiKeyMatch) < 2 {
return nil, "", fmt.Errorf("无法提取api_key")
}
// after: include a response snippet for diagnosis
apiKeyMatch := apiKeyRegex.FindStringSubmatch(infoText)
if len(apiKeyMatch) < 2 {
snippet := infoText
if len(snippet) > 200 {
snippet = snippet[:200]
}
return nil, "", fmt.Errorf("无法提取api_key, 响应片段: %q", snippet)
} Defensive patterns
Strategy: validation
Validate before calling
// Go: validate the info page body looks scrapable before regex extraction
if len(infoText) < 50 || strings.Contains(infoText, "<title>403") || strings.Contains(infoText, "captcha") {
return fmt.Errorf("info page unusable (len=%d), not attempting api_key extraction", len(infoText))
} Type guard
func extractableAPIKey(infoText string) bool {
return regexp.MustCompile(`api_key=([^"]+)`).MatchString(infoText)
} Try / catch
qr, _, err := plugin.GenerateQRCodeWithSig(...)
if err != nil {
if strings.Contains(err.Error(), "无法提取api_key") {
// endpoint format changed or blocked; retry once, then surface for manual update
return retryOrFail(err)
}
return err
} Prevention
- Send realistic User-Agent/Referer headers so the info endpoint serves the real page, not a block page.
- Log a response snippet whenever regex extraction fails to detect format drift early.
- Check HTTP status and body length before regex matching.
- Keep the scraping regexes in one place with tests against a saved real response.
When it happens
Trigger: generateQRCodeWithSig (called by handleGetStatus and handleRefreshQRCode) fetches the info page and FindStringSubmatch returns fewer than 2 groups because the body contains no api_key=... sequence.
Common situations: Weibo changed the QR info page layout or moved api_key into a JSON/JS payload; the request returned an error page, captcha, or login wall instead of the expected content; rate limiting or geo-blocking returning an interstitial; empty response due to network issues.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/63d6657836130696.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/weibo/weibo.go:1811
infoResp, err := client.Do(req)
if err != nil {
return nil, "", err
}
defer infoResp.Body.Close()
infoBody, err := io.ReadAll(infoResp.Body)
if err != nil {
return nil, "", err
}
// 响应是JSONP格式,提取JSON部分
infoText := string(infoBody)
// 提取api_key: 正则 api_key=(.*)"
apiKeyRegex := regexp.MustCompile(`api_key=([^"]+)`)
apiKeyMatch := apiKeyRegex.FindStringSubmatch(infoText)
if len(apiKeyMatch) < 2 {
return nil, "", fmt.Errorf("无法提取api_key")
}
apiKey := apiKeyMatch[1]
// 提取qrid: 正则 "qrid":"(.*?)"
qridRegex := regexp.MustCompile(`"qrid":"([^"]+)"`)
qridMatch := qridRegex.FindStringSubmatch(infoText)
if len(qridMatch) < 2 {
return nil, "", fmt.Errorf("无法提取qrid")
}
qrid := qridMatch[1]
// 第二步:使用api_key获取二维码图片
qrImageURL := fmt.Sprintf("https://v2.qr.weibo.cn/inf/gen?api_key=%s", apiKey)
qrReq, err := http.NewRequest("GET", qrImageURL, nil)
if err != nil {
return nil, "", err
}View on GitHub (pinned to beaa561337)