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

  1. Log the raw infoText on failure to see what the endpoint actually returned.
  2. Re-fetch — transient blocks/captchas often clear; add proper headers (User-Agent, Referer) so the endpoint serves the real page.
  3. Check whether Weibo changed the page and update the api_key regex to match the new format (e.g. JSON key "api_key":"...").
  4. 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

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)