xpzouying/xiaohongshu-mcp · warning
login status element not found
Error message
login status element not found
What it means
CheckLoginStatus concludes the user is NOT logged in when the `.main-container .user .link-wrapper .channel` element is absent from the explore page, and returns this error. Note the bug: errors.Wrap(err, ...) is called with err == nil here, so the resulting error is effectively errors.New("login status element not found"). It conflates 'definitely logged out' with 'page rendered differently than expected'.
Source
Thrown at xiaohongshu/login.go:33
func NewLogin(page *rod.Page) *LoginAction {
return &LoginAction{page: page}
}
func (a *LoginAction) CheckLoginStatus(ctx context.Context) (bool, error) {
// 加超时保护:只是查登录态的快速检查,不应无限挂(登录扫码的等待在 Login/WaitForLogin 里)
pp := a.page.Context(ctx).Timeout(30 * time.Second)
pp.MustNavigate("https://www.xiaohongshu.com/explore").MustWaitLoad()
time.Sleep(1 * time.Second)
exists, _, err := pp.Has(`.main-container .user .link-wrapper .channel`)
if err != nil {
return false, errors.Wrap(err, "check login status failed")
}
if !exists {
return false, errors.Wrap(err, "login status element not found")
}
return true, nil
}
// CurrentUser 当前登录用户的基础信息。
type CurrentUser struct {
Nickname string `json:"nickname"`
UserID string `json:"userId"`
}
// CurrentUser 从当前页面的 __INITIAL_STATE__ 读取登录用户信息。
// 需在 CheckLoginStatus 之后调用:复用已加载的 explore 页,不做额外导航。
func (a *LoginAction) CurrentUser(ctx context.Context) (*CurrentUser, error) {
pp := a.page.Context(ctx).Timeout(10 * time.Second)
res, err := pp.Eval(`() => {
const u = window.__INITIAL_STATE__ && window.__INITIAL_STATE__.user;View on GitHub (pinned to 332d196854)
Solutions
- Manually open the explore page in the same browser profile and inspect whether the selector still exists; update the CSS selector if the DOM changed
- Replace the fixed time.Sleep with rod's Wait/WaitRequestIdle or retry Has a few times before concluding logged-out
- Re-run the Login flow to refresh cookies, then call CheckLoginStatus again
- Return a typed 'not logged in' sentinel instead of relying on the wrapped (nil) error, and use errors.Is in callers
Example fix
// before
if !exists {
return false, errors.Wrap(err, "login status element not found")
}
// after
if !exists {
// 再等待重试一次,排除慢渲染导致的误判
pp.WaitStable(500 * time.Millisecond)
if exists2, _, _ := pp.Has(`.main-container .user .link-wrapper .channel`); !exists2 {
return false, errors.New("login status element not found (likely logged out)")
}
} Defensive patterns
Strategy: fallback
Validate before calling
// 调用前先确认有会话 cookie
cookies, _ := page.Cookies("https://www.xiaohongshu.com")
hasSession := false
for _, c := range cookies {
if c.Name == "web_session" && c.Value != "" {
hasSession = true
}
}
if !hasSession {
return errors.New("no session cookie, login required")
} Type guard
func isNotLoggedInErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "login status element not found")
} Try / catch
loggedIn, err := loginAction.CheckLoginStatus(ctx)
if err != nil {
if isNotLoggedInErr(err) {
// 回退:走完整登录流程后重查
if err := loginAction.Login(ctx); err != nil {
return err
}
loggedIn, err = loginAction.CheckLoginStatus(ctx)
}
if err != nil {
return err
}
}
_ = loggedIn Prevention
- Refresh session cookies proactively before long automation runs
- Prefer rod Wait/WaitStable over fixed time.Sleep before querying selectors
- Re-verify CSS selectors after Xiaohongshu frontend updates
- Treat 'element not found' as 'unknown state' and retry once before concluding logged-out
When it happens
Trigger: Calling CheckLoginStatus when: the session cookie expired so the page shows the logged-out layout; Xiaohongshu changed/expired the DOM class names (A/B tests, redesign); the 1-second sleep was not enough and the user menu hadn't rendered yet; a lightweight/anti-bot page variant rendered without the .main-container structure.
Common situations: Long-lived sessions expiring overnight; site frontend update renaming .link-wrapper/.channel classes; headless fingerprint flagged and served a degraded page; slow render where the element appears after the query but the library doesn't wait for it.
Related errors
AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05).
Data as JSON: /api/errors/1d657990be2b0aeb.
Report an issue: GitHub.