xpzouying/xiaohongshu-mcp · error

qrcode src is empty

Error message

qrcode src is empty

What it means

FetchQrcodeImage reads the src attribute of the '.login-container .qrcode-img' element; if the attribute is nil or an empty string it returns 'qrcode src is empty' along with false (not expired). It means the QR code image element exists but carries no image URL, so the login QR cannot be fetched.

Source

Thrown at xiaohongshu/login.go:107

func (a *LoginAction) FetchQrcodeImage(ctx context.Context) (string, bool, error) {
	pp := a.page.Context(ctx)

	// 导航到小红书首页,这会触发二维码弹窗
	pp.MustNavigate("https://www.xiaohongshu.com/explore").MustWaitLoad()

	time.Sleep(2 * time.Second)

	if exists, _, _ := pp.Has(".main-container .user .link-wrapper .channel"); exists {
		return "", true, nil
	}

	src, err := pp.MustElement(".login-container .qrcode-img").Attribute("src")
	if err != nil {
		return "", false, errors.Wrap(err, "get qrcode src failed")
	}
	if src == nil || len(*src) == 0 {
		return "", false, errors.New("qrcode src is empty")
	}

	return *src, false, nil
}

func (a *LoginAction) WaitForLogin(ctx context.Context) bool {
	pp := a.page.Context(ctx)
	ticker := time.NewTicker(500 * time.Millisecond)
	defer ticker.Stop()

	for {
		select {
		case <-ctx.Done():
			return false
		case <-ticker.C:
			el, err := pp.Element(".main-container .user .link-wrapper .channel")
			if err == nil && el != nil {
				return true

View on GitHub (pinned to 332d196854)

Solutions

  1. Wait for the QR image to finish loading (WaitVisible/WaitRequestIdle) before reading the src attribute
  2. Retry FetchQrcodeImage after a short delay — the src is often populated asynchronously
  3. Capture a screenshot when it fails to see whether a captcha/verify page replaced the login UI
  4. Update the '.login-container .qrcode-img' selector if the site markup changed

Example fix

// before
src, expired, err := login.FetchQrcodeImage(ctx)
if err != nil { return err }
// after
var src string
var expired bool
var err error
for i := 0; i < 3; i++ {
    src, expired, err = login.FetchQrcodeImage(ctx)
    if err == nil || !strings.Contains(err.Error(), "qrcode src is empty") { break }
    time.Sleep(2 * time.Second)
}
if err != nil { return err }
Defensive patterns

Strategy: retry

Validate before calling

_, err := page.Element(".login-container .qrcode-img")
// only proceed if the element exists; wait if err != nil

Try / catch

var src string; var err error
for i := 0; i < 3; i++ {
    src, _, err = login.FetchQrcodeImage(ctx)
    if err == nil || !strings.Contains(err.Error(), "qrcode src is empty") { break }
    time.Sleep(2 * time.Second)
}
if err != nil { return err }

Prevention

When it happens

Trigger: Calling LoginAction.FetchQrcodeImage (xiaohongshu/login.go:107) when the qrcode img has no src — the QR hasn't been generated yet after page load, the login container is a fallback variant without the expected element, or a verify/interstitial page replaced the login page.

Common situations: Fetching the QR immediately after navigation before the login widget finishes initializing; XHS serving a slider-captcha instead of the QR login; DOM changes renaming .qrcode-img so the selector matches a stale/empty placeholder img.

Related errors


AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05). Data as JSON: /api/errors/0f2b4a0e55a5e007. Report an issue: GitHub.