jackwener/OpenCLI · error · CommandExecutionError
Ctrip train cards rendered but parser did not find required
Error message
Ctrip train cards rendered but parser did not find required train anchors
What it means
Thrown as CommandExecutionError when the page visibly rendered train cards (scroll-until counted renderedCardCount > 0) but the extractor produced zero parseable rows. This means the DOM anchors the extractor requires (per-train identifiers) were not found, i.e. the page layout changed relative to the parser's expectations.
Source
Thrown at clis/ctrip/train.js:69
const limit = parseListLimit(kwargs.limit);
const searchUrl = buildTrainListUrl(fromName, toName, date);
await page.goto(searchUrl);
const waitResult = await page.evaluate(WAIT_FOR_TRAINS_JS);
if (waitResult === 'captcha') {
throw new AuthRequiredError('trains.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
}
if (waitResult !== 'content') {
throw new CommandExecutionError(`Ctrip train page did not render train cards (state=${String(waitResult)})`);
}
const renderedCardCount = await page.evaluate(buildScrollUntilJs('.card-white.list-item', limit));
const raw = await page.evaluate(buildTrainExtractJs());
if (!Array.isArray(raw)) {
throw new CommandExecutionError('Ctrip train DOM extraction returned malformed rows');
}
if (raw.length === 0) {
if (Number(renderedCardCount) > 0) {
throw new CommandExecutionError('Ctrip train cards rendered but parser did not find required train anchors');
}
throw new EmptyResultError('ctrip train', `No trains for ${fromName} to ${toName} on ${date}`);
}
return raw.slice(0, limit).map((r, i) => ({
rank: i + 1,
trainNo: r.trainNo,
departureTime: r.departureTime,
departureStation: r.departureStation,
arrivalTime: r.arrivalTime,
arrivalStation: r.arrivalStation,
duration: r.duration,
fromPrice: r.fromPrice,
seats: Array.isArray(r.seats) && r.seats.length ? r.seats.join(' / ') : null,
url: searchUrl,
}));
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect a rendered card in DevTools and update the anchors required by buildTrainExtractJs.
- Re-run after a full page load / extra settle delay in case anchors render late.
- Check for Ctrip A/B variants by re-running in a fresh session.
Example fix
// before (extractor selector)
document.querySelector('.train-num')
// after (updated to current markup)
document.querySelector('[data-train-no], .train-number') Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
null
Try / catch
try { return await runTrainList(opts); } catch (e) { if (e instanceof CommandExecutionError && /train anchors/.test(e.message)) { await sleep(3000); return retryOnce(opts); } throw e; } Prevention
- Allow extra settle time before extraction so late-rendered anchors exist
- Update required-anchor selectors after Ctrip redesigns
- Compare rendered card count vs extracted rows to detect drift early
When it happens
Trigger: buildScrollUntilJs('.card-white.list-item', limit) counted cards, but buildTrainExtractJs() returned an empty array because required train anchors (train number elements etc.) are missing or renamed in the DOM.
Common situations: Ctrip partial redesign: card wrapper class unchanged but inner anchor attributes/classes changed; lazy-rendered fields not present when extraction runs; A/B test variant lacking the expected anchors.
Related errors
- Ctrip round-trip flight cards rendered but parser did not fi
- Ctrip train DOM extraction returned malformed rows
- powerchina search
- Not a git repository
- Ctrip cruise cards rendered but parser did not find required
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/9901cc2239d662aa.
Report an issue: GitHub.