jackwener/OpenCLI · error · AuthRequiredError

xueqiu.com

Error message

xueqiu.com

What it means

throwFirstPageFailure maps the classification of the first comments response to a typed error. When the first page is classified as 'auth' (HTTP 401/403 or login-required text) or 'anti-bot' (captcha/WAF HTML), collectCommentRows throws AuthRequiredError('xueqiu.com', 'Stock discussions require login or challenge clearance'). Xueqiu requires a logged-in, challenge-cleared session to read stock discussions.

Source

Thrown at clis/xueqiu/comments.js:45

function toFiniteCount(value) {
    const count = Number(value ?? 0);
    return Number.isFinite(count) ? count : 0;
}
function normalizeIdentifier(value) {
    if (typeof value === 'string')
        return value.trim();
    if (typeof value === 'number' && Number.isFinite(value))
        return String(value);
    return '';
}
function buildPaginationStopMessage(requestNumber, collected, target, reason) {
    return `xueqiu comments pagination stopped after request ${requestNumber}, `
        + `collected ${collected}/${target} items, `
        + `reason: ${reason}`;
}
function throwFirstPageFailure(kind, symbol) {
    if (kind === 'auth' || kind === 'anti-bot') {
        throw new AuthRequiredError('xueqiu.com', 'Stock discussions require login or challenge clearance');
    }
    if (kind === 'argument') {
        throw new ArgumentError(`xueqiu comments received an invalid symbol: ${symbol}`);
    }
    if (kind === 'empty') {
        throw new EmptyResultError(`xueqiu/comments ${symbol}`, `No discussion data found for ${symbol}`);
    }
    throw new CommandExecutionError(`Unexpected response while loading xueqiu comments for ${symbol}`, 'Run the command again with --verbose to inspect the raw site response.');
}
/**
 * Extract the raw item list from one classified JSON payload.
 *
 * @param json Raw parsed JSON payload from browser fetch.
 * @returns Discussion items when the response shape is usable.
 */
export function getCommentItems(json) {
    if (!isRecord(json))
        return [];

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run the xueqiu auth login command and complete login in the opened browser to obtain xq_a_token
  2. If recently logged in, visit https://xueqiu.com/ manually and solve any captcha/WAF challenge, then retry
  3. Slow down request rate or wait if you suspect rate limiting triggered the anti-bot page
  4. Retry from a residential/different network if datacenter IP challenges persist

Example fix

// before (calling comments while anonymous)
await collectCommentRows({ symbol: 'SH600519', ... });
// after (guard on quickCheck first)
if (!await hasXueqiuAccessToken(page)) {
  throw new AuthRequiredError('xueqiu.com', 'Login first: opencli xueqiu auth login');
}
await collectCommentRows({ symbol: 'SH600519', ... });
Defensive patterns

Strategy: try-catch

Validate before calling

const cookies = await page.getCookies({ url: 'https://xueqiu.com' });
if (!cookies.some(c => c.name === 'xq_a_token' && c.value)) {
  throw new Error('Run `opencli xueqiu auth login` before fetching comments');
}

Try / catch

try {
  const rows = await collectCommentRows(opts);
} catch (e) {
  if (e.name === 'AuthRequiredError') {
    console.error('Login to xueqiu (and clear any captcha) before fetching comments');
  } else throw e;
}

Prevention

When it happens

Trigger: First request to https://xueqiu.com/query/v1/symbol/search/status returns 401/403, or returns text/html containing captcha/challenge/aliyun_waf markers, while running `opencli xueqiu comments <symbol>` with an anonymous or WAF-challenged session.

Common situations: Running without ever completing `xueqiu auth login`; xq_a_token cookie expired; xueqiu's Aliyun WAF issued a captcha after heavy scraping; running from a datacenter IP that gets challenged.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/d9f963c697dc8c4d. Report an issue: GitHub.