fish2018/pansou · error
未找到ptsigx
Error message
未找到ptsigx
What it means
extractLoginInfo (plugin/qqpd/qqpd.go:1857) matched the ptuiCB callback and URL, but the regex `ptsigx=([A-Za-z0-9]+)` found no ptsigx parameter in the extracted URL, so it returns '未找到ptsigx'. ptsigx is the signing token required for the follow-up check_sig cookie exchange, so login cannot proceed without it.
Solutions
- Log the extracted URL and inspect which query parameters are actually present
- Update the ptsigx regex if QQ changed the parameter name or charset (e.g. allowing '_' or '%')
- Handle alternate URL forms (URL-decode first in case the sign param is percent-encoded)
- Regenerate the QR code and retry the login flow
Example fix
// before ptsigxRe := regexp.MustCompile(`ptsigx=([A-Za-z0-9]+)`) // after ptsigxRe := regexp.MustCompile(`ptsigx=([^&']+)`)
Defensive patterns
Strategy: validation
Validate before calling
// verify expected query params before extraction
u, err := url.Parse(extractedURL)
if err != nil {
return fmt.Errorf("bad login url: %w", err)
}
if u.Query().Get("ptsigx") == "" {
return errors.New("login url missing ptsigx")
} Type guard
func hasPtsigx(loginURL string) bool {
u, err := url.Parse(loginURL)
return err == nil && u.Query().Get("ptsigx") != ""
} Try / catch
ptsigx, uin, err := p.extractLoginInfo(bodyStr)
if err != nil {
if err.Error() == "未找到ptsigx" {
// login URL shape changed or sign missing; restart QR flow with diagnostics
return nil, fmt.Errorf("login url lacked ptsigx, refresh QR: %w", err)
}
return nil, err
} Prevention
- Log the full extracted login URL when parsing fails
- Use url.Parse + Query().Get instead of narrow character-class regexes
- URL-decode the callback URL before regex matching
- Add regression tests with the latest recorded ptqrlogin URLs
When it happens
Trigger: checkQRLoginStatus -> extractLoginInfo: the ptuiCB URL exists but lacks a ptsigx query parameter — QQ returned a redirect URL variant without the sign token.
Common situations: QQ A/B-testing a new login URL shape, the URL being a jump/verify URL (e.g. needing an extra verification step), or a truncated/malformed callback URL.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/9edb8659ba08e6fd.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/qqpd/qqpd.go:1857
start := strings.Index(responseText, "ptuiCB(")
if start == -1 {
return "", "", fmt.Errorf("未找到ptuiCB")
}
// 简单解析,提取URL部分
re := regexp.MustCompile(`ptuiCB\('0','0','([^']+)'`)
matches := re.FindStringSubmatch(responseText)
if len(matches) < 2 {
return "", "", fmt.Errorf("无法解析响应")
}
url := matches[1]
// 提取ptsigx
ptsigxRe := regexp.MustCompile(`ptsigx=([A-Za-z0-9]+)`)
ptsigxMatches := ptsigxRe.FindStringSubmatch(url)
if len(ptsigxMatches) < 2 {
return "", "", fmt.Errorf("未找到ptsigx")
}
ptsigx := ptsigxMatches[1]
// 提取uin
uinRe := regexp.MustCompile(`uin=(\d+)`)
uinMatches := uinRe.FindStringSubmatch(url)
if len(uinMatches) < 2 {
return "", "", fmt.Errorf("未找到uin")
}
uin := uinMatches[1]
return ptsigx, uin, nil
}
// fetchFullCookie 获取完整Cookie
func (p *QQPDPlugin) fetchFullCookie(uin, ptsigx, setCookieHeader string) (string, error) {
checkSigURL := fmt.Sprintf("https://ptlogin2.pd.qq.com/check_sig?pttype=1&uin=%s&service=ptqrlogin&nodirect=1&ptsigx=%s&s_url=https%%3A%%2F%%2Fpd.qq.com%%2Fexplore&f_url=&ptlang=2052&ptredirect=101&aid=1600001587&daid=823&j_later=0&low_login_hour=0®master=0&pt_login_type=3&pt_aid=0&pt_aaid=16&pt_light=0&pt_3rd_aid=0", uin, ptsigx)
View on GitHub (pinned to beaa561337)