xpzouying/xiaohongshu-mcp · error

get qrcode src failed

Error message

get qrcode src failed

What it means

FetchQrcodeImage navigates to the xiaohongshu explore page, checks whether the user is already logged in, and otherwise locates the login QR-code image (.login-container .qrcode-img) and reads its src attribute. 'get qrcode src failed' wraps the rod error from MustElement/Attribute — normally that the QR-code element was not found within rod's default element-wait timeout, so no login dialog was rendered.

Source

Thrown at xiaohongshu/login.go:104

	return nil
}

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:

View on GitHub (pinned to 332d196854)

Solutions

  1. First confirm login state independently: if already logged in, don't call FetchQrcodeImage — check the returned second bool or verify the .channel element yourself
  2. Replace the fixed time.Sleep(2s) with an explicit wait for the .login-container .qrcode-img selector (rod's Element already polls; extend the page timeout)
  3. Dump the page HTML (page.MustElement("body").MustHTML()) when this fires to see whether a captcha/slider or a redesigned login modal replaced the QR dialog
  4. Update the CSS selectors to match the current xiaohongshu login DOM after inspecting the live page
  5. Check for risk-control/anti-bot interstitials; consider a real browser profile (user data dir) instead of a clean headless one

Example fix

// before
pp.MustNavigate("https://www.xiaohongshu.com/explore").MustWaitLoad()
time.Sleep(2 * time.Second)
// after
pp.MustNavigate("https://www.xiaohongshu.com/explore").MustWaitLoad()
pp.Timeout(30 * time.Second).MustElement(".login-container .qrcode-img") // explicit wait instead of fixed sleep
src, err := pp.Timeout(10*time.Second).Element(".login-container .qrcode-img")
Defensive patterns

Strategy: validation

Validate before calling

// check login state before requesting a QR code
exists, q, err := page.Has(".main-container .user .link-wrapper .channel")
if err == nil && exists { return "", true, nil } // already logged in

Type guard

func qrDialogVisible(p *rod.Page) bool {
    el, err := p.Timeout(2*time.Second).Element(".login-container .qrcode-img")
    return err == nil && el != nil
}

Try / catch

src, loggedIn, err := login.FetchQrcodeImage(ctx)
if err != nil {
    if strings.Contains(err.Error(), "get qrcode src failed") {
        // dialog absent: maybe already logged in or a captcha page; inspect page HTML
        html, _ := page.Element("body")
        log.Printf("login page state: %v", html)
    }
    return err
}

Prevention

When it happens

Trigger: Calling FetchQrcodeImage while already logged in but the .channel presence check (Has) misses due to selector drift, so the code proceeds to look for a QR dialog that never appears; the login dialog renders slowly or under a different class name after a site update; anti-bot measures show a slider/captcha instead of the QR code; the page failed to fully load in the 2s fixed sleep window.

Common situations: Reusing a session cookie so no QR appears but the login-status selector changed; running headless and getting a risk-control page instead of the normal login modal; xiaohongshu renaming .login-container/.qrcode-img in a front-end release; slow network making 2 seconds insufficient for the modal.

Related errors


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