jackwener/OpenCLI · error · CommandExecutionError
IMDb blocked this request
Error message
IMDb blocked this request
What it means
The imdb top command throws CommandExecutionError('IMDb blocked this request') when, after navigating to https://www.imdb.com/chart/top/ and waiting 2 seconds, isChallengePage(page) detects an anti-bot challenge page. IMDb served a CAPTCHA/interstitial instead of the chart, so the command aborts before extracting the ItemList JSON-LD.
Source
Thrown at clis/imdb/top.js:24
*/
cli({
site: 'imdb',
name: 'top',
access: 'read',
description: 'IMDb Top 250 Movies',
domain: 'www.imdb.com',
strategy: Strategy.PUBLIC,
browser: true,
args: [
{ name: 'limit', type: 'int', default: 20, help: 'Number of results' },
],
columns: ['rank', 'title', 'rating', 'votes', 'genre', 'url'],
func: async (page, args) => {
const url = forceEnglishUrl('https://www.imdb.com/chart/top/');
await page.goto(url);
await page.wait(2);
if (await isChallengePage(page)) {
throw new CommandExecutionError('IMDb blocked this request', 'Try again with a normal browser session or extension mode');
}
// Extract the ItemList JSON-LD block which contains all chart entries
const ld = await extractJsonLd(page, 'ItemList');
if (!ld || !Array.isArray(ld.itemListElement)) {
throw new CommandExecutionError('Could not find chart data on page', 'IMDb may have changed their page structure');
}
const limit = Math.max(1, Math.min(Number(args.limit) || 20, 250));
const items = ld.itemListElement.slice(0, limit);
return items.map((entry, index) => {
const item = entry.item || {};
const rating = item.aggregateRating || {};
const genre = Array.isArray(item.genre)
? item.genre.join(', ')
: String(item.genre || '');
// Normalize relative URLs to absolute IMDb URLs
let itemUrl = item.url || '';
if (itemUrl && !/^https?:\/\//.test(itemUrl)) {
itemUrl = 'https://www.imdb.com' + itemUrl;View on GitHub (pinned to 49907e53dc)
Solutions
- Retry with a normal browser session or extension mode.
- Add longer waits/backoff between chart fetches; chart data changes rarely so cache results.
- Use a different/residential IP if blocks persist.
- Clear or refresh cookies/login state in the automated browser.
Example fix
// before
setInterval(() => imdbTop({ limit: 250 }), 60_000); // every minute
// after
setInterval(() => imdbTop({ limit: 250, mode: 'extension' }), 3_600_000); // hourly + real session Defensive patterns
Strategy: retry
Try / catch
try {
return await imdbTop({ limit: 250 });
} catch (e) {
if (/IMDb blocked this request/.test(e.message)) {
await sleep(60_000);
return retryWithBackoff(() => imdbTop({ limit: 250, mode: 'extension' }), { attempts: 3 });
}
throw e;
} Prevention
- Poll the Top 250 infrequently (hourly/daily) and cache — it changes rarely.
- Use extension/normal browser mode with real cookies for chart scraping.
- Avoid shared datacenter IPs that IMDb flags proactively.
- Add backoff and jitter to all scheduled chart jobs.
When it happens
Trigger: page.goto of https://www.imdb.com/chart/top/, page.wait(2), then isChallengePage(page) returns true — the chart page was replaced by a bot challenge.
Common situations: Frequent polling of the Top 250 chart from a server IP, headless-browser detection, flagged cookies, or running inside CI/cloud where IMDb's anti-bot is aggressive.
Related errors
- IMDb blocked this request
- IMDb blocked this request
- IMDb blocked this request
- [taxonomy=selector_drift] site=jianyu command=search blocked
- 触发了验证码,请先在浏览器中完成验证
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b44e633ac70b7c86.
Report an issue: GitHub.