Tracking box-office performance across multi-year theatrical runs typically fails due to inconsistent schemas and missing production budget disclosures. While media reporting focuses on opening weekends, downstream financial modeling requires metrics like the "legs" multiplier (total domestic gross divided by the opening weekend) and production budget data to evaluate theatrical profitability.
The Numbers tracks theatrical data back to 1980 for yearly rankings and 1998 for daily charts. Automating collection from this catalog provides structured box-office snapshots without building custom HTML parsers for varying table layouts.
Financial Metrics Available on The Numbers
Film analytics require linking theatrical grosses directly to cost metrics. Using The Numbers Box Office Scraper, queries return structured records across distinct operational modes:
-
byTitle: Fetches complete film financial profiles, includingproductionBudget,domesticBoxOffice,internationalBoxOffice,worldwideBoxOffice,openingWeekendGross, and calculatedlegs. -
weekend,daily, andweekly: Pulls periodic ranking charts containingrank,previousRank,gross,theaterCount,theaterAverage, anddaysInRelease. -
yearly: Emits ranked box office summaries for specific calendar years withgrossForYearandticketsSold. -
releaseSchedule: Returns upcoming or current releases withreleaseDate,releaseType, anddomesticBoxOfficeToDate.
The data schema omits empty fields entirely rather than passing empty strings or null values. For instance, if a studio does not disclose a film's productionBudget, that key does not appear in the record payload.
Configuring Chart and Financial Queries
The scraper runs on standard datacenter IPs over HTTP without requiring authenticated sessions or residential proxies. The primary parameters control the query target and returned volume.
Parameter Definitions
-
mode: Dictates the target endpoint (weekend,daily,weekly,yearly,byTitle, orreleaseSchedule). -
chartDate: Formatted asYYYY-MM-DD. Forweekendandweeklyqueries, dates automatically snap to the nearest Friday on or prior to the input date. -
movieTitle: Used inbyTitlemode to query specific titles. -
year: Integer value (1980 through current) defining the target year foryearlycharts. -
minGross: Filters out long-tail releases by dropping any record where the period gross falls below the threshold. -
maxItems: Sets a hard cap on returned dataset items (between 1 and 200).
Querying Franchise Financials with Python
When querying by title, common franchise names return multiple entries. A search for "Toy Story" yields original releases, sequels, and spin-offs. The year field in the response resolves ambiguities.
from apify_client import ApifyClient
client = ApifyClient("YOUR_API_TOKEN")
run_input = {
"mode": "byTitle",
"movieTitle": "Avatar",
"maxItems": 5
}
run = client.actor("crawlerbros/the-numbers-box-office-scraper").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(f"Title: {item.get('title')} ({item.get('year')})")
print(f"Budget: ${item.get('productionBudget', 0):,}")
print(f"Worldwide: ${item.get('worldwideBoxOffice', 0):,}")
print(f"Legs: {item.get('legs', 'N/A')}")
Filtering Historical Box Office Charts
For periodic or studio-specific reports, filter parameters can prune payloads before results are written to the default dataset.
{
"mode": "yearly",
"year": 2025,
"distributor": "Walt Disney",
"genre": "Action",
"minGross": 10000000,
"maxItems": 50
}
This configuration extracts Disney-distributed action releases in 2025 earning at least $10,000,000, filtering out smaller limited runs.
Step-by-Step Run Walkthrough
Executing the scraper programmatically follows the standard Apify task pattern:
-
Select the target mode: Choose
byTitlefor movie economics,releaseSchedulefor calendar tracking, or chart modes (daily,weekend,weekly,yearly) for comparative rankings. -
Apply filter criteria: Constrain extraction using
distributor,genre, orminGrossto reduce unnecessary result emissions. -
Define execution caps: Set
maxItemsto restrict dataset growth to the exact number of top results needed. - Trigger the run and consume output: Start the scraper via the API and iterate over the emitted dataset items.
run_input = {
"mode": "weekend",
"chartDate": "2026-07-04",
"maxItems": 20
}
run = client.actor("crawlerbros/the-numbers-box-office-scraper").call(run_input=run_input)
dataset_items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
Pricing and Cost Calculation
This actor uses a PAY_PER_EVENT pricing model. Billing is determined exclusively by two charge events:
-
Actor Start (
apify-actor-start): Flat fee of $0.005 per GB of memory allocated to the run, charged once when the run initializes. -
Result (
apify-default-dataset-item): Flat fee per record written to the default dataset.
Result pricing scales with account volume tiers:
- FREE: $0.005 per result
- BRONZE: $0.00433 per result
- SILVER: $0.00367 per result
- GOLD, PLATINUM, DIAMOND: $0.003 per result
For example, running a weekly box-office extraction returning a top-20 chart (maxItems: 20) on the FREE tier with 1 GB of memory costs $0.005 for the run start and $0.10 for the 20 returned records (20 × $0.005), totaling $0.105.
Operational Constraints
This scraper does not bypass paywalls to fetch proprietary data. It cannot access subscriber-only features such as "Bankability" talent-value indices or The Numbers Business Report. Furthermore, lifetime distributor aggregation pages (/market/distributor/<name>) return HTTP 404 errors on the source site and are not supported.
Dates submitted prior to 1998 for daily, weekend, and weekly charts yield an empty dataset with a status notification rather than historical records. For historical studies spanning before 1998, data extraction must rely on the yearly mode, which contains records back to 1980. Pipeline designs must account for these date limits when constructing automated backfills.
If you want to reproduce this, the Actor is The Numbers Box Office Scraper. Read its input schema before the first run -- most failed runs are a missing required field, not a block.
Top comments (0)