AniList Scraper: Anime, Manga & Studio Data
Pricing
from $1.00 / 1,000 title scrapeds
AniList Scraper: Anime, Manga & Studio Data
Scrape AniList via GraphQL: anime and manga titles, scores, popularity, genres, studios, staff, airing schedules and relations. Rich metadata for media apps.
Pricing
from $1.00 / 1,000 title scrapeds
Rating
0.0
(0)
Developer
Arman Hossain
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
5 hours ago
Last modified
Categories
Share

AniList Scraper pulls structured anime and manga metadata straight from the AniList GraphQL API, titles in three scripts, scores, popularity, favourites, genres, community tags, studios, airing dates and full synopses.
Give it a list of search terms, or skip search entirely and browse a whole season by genre. Either way you get one clean dataset row per title. No proxy setup, no browser, no credentials to manage.
What you get
| Output field | Meaning |
|---|---|
id | AniList media ID, stable, use it as your join key |
titleRomaji, titleEnglish, titleNative | All three official title forms. titleEnglish is null when AniList has no licensed English title |
type | ANIME or MANGA |
format | TV, MOVIE, OVA, ONA, SPECIAL, MANGA, NOVEL, ONE_SHOT |
status | FINISHED, RELEASING, NOT_YET_RELEASED, CANCELLED, HIATUS |
episodes, chapters | Episode count for anime, chapter count for manga, the other is null |
averageScore | Weighted community score out of 100 |
popularity, favourites | Users with the title on a list, and users who favourited it |
genres | AniList's curated genre list |
tags | Community tags, ranked most-relevant first |
studios | Producing studios, main studio first |
startDate, endDate | YYYY-MM-DD, degrading to YYYY-MM or YYYY when AniList only knows part of the date |
season | Airing season and year, e.g. SPRING 2013 |
coverImage | Highest-resolution cover art URL |
description | Synopsis as clean plain text, AniList's stray <br> and <i> tags stripped |
scrapedAt | Run timestamp |
A RUN_SUMMARY record in the key-value store holds per-run counts, per-source counts, the filters applied, the number of API requests spent and any query that failed.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
searchTerms | array | [] | Title searches, one query each, ranked by relevance. Empty = browse using the filters below. |
mediaType | string | ANIME | ANIME or MANGA. |
season | string | - | WINTER, SPRING, SUMMER or FALL. Anime only. |
seasonYear | integer | - | Airing year, e.g. 2024. |
genres | array | [] | Exact AniList genre names. A title must carry every genre listed. |
maxResults | integer | 100 | Total titles saved across the run. Split evenly between search terms. |
Which combinations make sense
searchTermsalone, the fastest way to enrich a known list of titles.season+seasonYearwith nosearchTerms, the seasonal chart, most popular first. This is the mode to schedule.genresnarrows either mode. Genres are ANDed, so["Action", "Fantasy"]returns only titles carrying both.seasonwithoutseasonYearmatches that season in every year, usually not what you want.
Example input
{"searchTerms": ["attack on titan", "cowboy bebop"],"mediaType": "ANIME","genres": ["Action"],"maxResults": 12}
Output
A real record from the run above, abridged in the long fields:
{"id": 16498,"titleRomaji": "Shingeki no Kyojin","titleEnglish": "Attack on Titan","titleNative": "進撃の巨人","type": "ANIME","format": "TV","status": "FINISHED","episodes": 25,"chapters": null,"averageScore": 85,"popularity": 1038684,"favourites": 85824,"genres": ["Action", "Drama", "Fantasy", "Mystery"],"tags": ["Kaiju", "Revenge", "Tragedy", "Military", "Henshin", "…"],"studios": ["WIT STUDIO", "Pony Canyon", "Kodansha", "Production I.G", "…"],"startDate": "2013-04-07","endDate": "2013-09-28","season": "SPRING 2013","coverImage": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx16498-buvcRTBx4NSm.jpg","description": "Several hundred years ago, humans were nearly exterminated by titans. …","scrapedAt": "2026-08-06T11:29:28.483Z"}
RUN_SUMMARY:
{"sourcesRequested": 2,"sourcesFailed": 0,"failures": [],"titlesSaved": 9,"titlesPerSource": { "attack on titan": 6, "cowboy bebop": 3 },"apiRequests": 2,"rateLimitPerMin": 30,"filters": {"searchTerms": ["attack on titan", "cowboy bebop"],"mediaType": "ANIME","season": null,"seasonYear": null,"genres": ["Action"],"maxResults": 12},"finishedAt": "2026-08-06T11:29:30.148Z"}
Use cases
1. Build an anime tracking app. Seed your catalogue with the current season, then re-run weekly to pick up score and episode-count changes.
{"mediaType": "ANIME","season": "SPRING","seasonYear": 2024,"maxResults": 300}
2. Analyse seasonal release trends. Run the same query across seasons and compare studio output, genre mix and average scores. Change season/seasonYear per run and diff on id.
{"mediaType": "ANIME","season": "FALL","seasonYear": 2024,"genres": ["Action"],"maxResults": 200}
3. Media licensing research. Pull manga by genre with chapter counts, status and publisher studios to find completed series with high favourites-to-popularity ratios.
{"mediaType": "MANGA","genres": ["Psychological", "Thriller"],"maxResults": 150}
Limits and behaviour
- GraphQL POST, fixed query. Every request asks for the same field set, so 50 titles cost exactly one request regardless of filters.
- Self-pacing rate limiter. AniList advertises its budget in rate-limit headers and the Actor reads it from the first response, then spaces requests to match. It currently advertises 30 requests/minute; AniList's documentation still describes 90/min, so the Actor trusts the header rather than the docs. A
429is honoured viaretry-after. - Null filters are omitted, not sent. AniList applies an explicit
nullvariable as a literal filter,season: nullmatches only titles with no season and returns nothing. Unset filters are dropped from the variables object entirely. maxResultsis a total, split evenly. With two search terms andmaxResults: 12, each term gets a budget of 6. A term that has fewer matches simply returns fewer; the leftover is not redistributed.- AniList caps
pageInfo.totalat 5000 for broad browse queries, so treat it as "at least 5000", not an exact count. Page size is capped at 50 server-side. - A failing query never aborts the run. It is logged, recorded in
RUN_SUMMARY.failures, and the next source proceeds. The Actor only errors out if every source fails. - Transient errors are retried. 429 and 5xx get three attempts with linear backoff. GraphQL validation errors fail fast, because retrying a malformed query never helps.
- Public data only. No authentication, no personal data, no access-control bypass. AniList's content is user-contributed and licensed for reuse.
FAQ
Do I need a proxy? No. Proxy configuration is not required to run this Actor.
Do I need an AniList account or API key? No. You supply no credentials.
What happens if AniList is unavailable? The failing query is reported in RUN_SUMMARY.failures and the run continues with the next source. The run only fails outright if every source failed.
Can I schedule it? Yes, it is designed for scheduled runs. Weekly seasonal sweeps are the most common pattern; diff on id plus averageScore to catch score drift.
Why is titleEnglish sometimes null? AniList only carries an English title when one has been officially licensed. Fall back to titleRomaji, which is always present.
Why did a search return fewer titles than I asked for? Either the search has few matches, or your genres filter excluded the rest, genres are ANDed. RUN_SUMMARY.titlesPerSource shows the count for each term so you can tell the two apart.
Can I get staff and character data? Not in this Actor. The query shape is deliberately fixed so per-title cost stays constant; staff and character edges would multiply request volume per title.
Can I integrate it with something else? Yes, Apify API, client libraries, webhooks, scheduled runs, dataset exports (JSON/CSV/Excel) or MCP. Output is structured JSON.
API example
curl -X POST "https://api.apify.com/v2/acts/arman-bd~anilist-anime-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"mediaType": "ANIME","season": "SPRING","seasonYear": 2024,"maxResults": 75}'
JavaScript example
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('arman-bd/anilist-anime-scraper').call({searchTerms: ['frieren', 'chainsaw man'],mediaType: 'ANIME',maxResults: 20,});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const t of items) console.log(`${t.titleEnglish ?? t.titleRomaji}, ${t.averageScore} (${t.season})`);