AniList Anime & Manga Scraper - Scores, Charts, Full Metadata
Pricing
from $1.80 / 1,000 anime or manga records
AniList Anime & Manga Scraper - Scores, Charts, Full Metadata
Scrape AniList anime and manga: titles (romaji/English/native), scores, popularity, favourites, genres, studios, airing schedule, synopses, charts (trending, popular, top-rated, most-favourited), keyword search and URL/ID lookup.
Pricing
from $1.80 / 1,000 anime or manga records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
15 days ago
Last modified
Categories
Features
Share
AniList Scraper: Anime & Manga Scores, Charts & Full Metadata
AniList Scraper turns AniList into structured anime and manga data. Search by keyword, pull ranked charts (trending, popular, top rated, most favourited), or paste AniList links or ids, and get titles in romaji, English and native script, scores, popularity, favourites, genres, studios, format, status, episode and chapter counts, airing schedule and a cleaned synopsis. Export to JSON, CSV or Excel, or read the results straight through the API.
Why This Scraper?
- Three ways to find media. Keyword search (multiple terms merged and de-duplicated), curated charts, or paste AniList links (media pages or search and chart pages) or bare numeric ids. No need to build URLs by hand.
- Anime and manga in one actor. Switch media type and every mode, search, charts and URL lookup, adapts automatically.
- Rich per-title records. Romaji, English and native titles, average and mean score, popularity, favourites, genres, main studios, format, status, episode/chapter/volume counts, season and air dates, next-airing episode with timestamp, cover art, banner image and a cleaned (HTML-stripped) synopsis.
- Curated charts on demand. Trending now, most popular, top rated, or most favourited, for anime or manga separately.
- Adult content off by default. Search and chart results exclude adult titles unless you turn it on.
- Built for schedules. Incremental mode returns only new, updated and reappeared records on recurring runs, and a refused run fails loudly instead of returning an empty dataset.
- Resume large pulls. Continue an interrupted run from its run or dataset id without paying twice for records it already collected.
Use Cases
- Anime/manga database and app builders: gather full catalog records, scores, popularity and studio credits to populate a browsable site or app.
- Trend and release tracking: watch the trending and most-favourited charts to catch what is rising, and use next-airing episode data for release calendars.
- Recommendation engines and scouting: combine genres, studios, scores and favourites across many titles for similarity or ranking models.
- Fan wikis and content sites: pull synopses, cover art and metadata to populate season guides, reviews or news posts.
- Market and licensing research: monitor score and popularity movement for specific titles over time with incremental mode.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
id | 999001 |
idMal | 888001 |
url | AniList link to the anime or manga |
titleRomaji / titleEnglish / titleNative | "Sample Romaji Title" / "Sample English Title" / "サンプルタイトル" |
format | "TV" (also "MOVIE", "OVA", "ONA", "MANGA", "NOVEL", and more) |
status | "FINISHED" (also "RELEASING", "NOT_YET_RELEASED", "CANCELLED", "HIATUS") |
episodes / chapters / volumes | 24 / null / null (anime carries episodes, manga carries chapters and volumes) |
durationMin | 23 |
averageScore / meanScore | 78 / 77 |
popularity / favourites | 45000 / 9000 |
genres | ["Fantasy", "Adventure"] |
countryOfOrigin | "JP" |
isAdult | false |
description | cleaned synopsis text, HTML tags stripped |
season / seasonYear | "SPRING" / 2025 |
startDate / endDate | "2025-04-01" / "2025-09-20" |
studios | ["Sample Studio"] |
nextAiringEpisode / nextAiringAt | 5 / 1750000000 (null once a series has finished) |
coverImage | cover art URL |
bannerImage | banner image URL (may be empty for some titles) |
When Incremental mode is on, every record also carries changeType (NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED), changedFields, firstSeenAt and lastSeenAt.
More fields per record
Each record also carries coverUrl, anilistUrl, genresText, studiosText, synonyms, source, hashtag, trending, tags (with rank), rankings, trailerUrl and externalLinks. For incremental users these new fields do not cause a one-time wave of UPDATED rows: they only count as changes once a stored record already contains them, and trending and rankings never count as changes.
How to Use
- Pick a mode:
search(by keyword),charts(ranked list), orurl(paste AniList links or ids). - Set Media type (anime or manga) and fill in the fields for that mode.
- Set Max records and Max pages to control run size and cost (search and charts modes, and each pasted search or chart link in URL mode; pasted media links and ids are always all returned).
- Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
Search for anime by keyword:
{"mode": "search","mediaType": "ANIME","searchTerms": ["sample title"],"maxMedia": 10}
Top-rated manga chart:
{"mode": "charts","mediaType": "MANGA","chartKind": "TOP_RATED","maxMedia": 20}
Paste AniList links or ids:
{"mode": "url","urls": ["https://anilist.co/anime/999001", "888002"]}
URL mode link shapes
| Shape | Example | Result |
|---|---|---|
| Anime detail | https://anilist.co/anime/154587 | one anime record |
| Manga detail | https://anilist.co/manga/30013 | one manga record |
| Bare numeric id | 154587 | the record with that id |
| Keyword search page | https://anilist.co/search/anime?search=frieren (optional genres, format, status, season, year, sort, page query options) | the same results as Search mode with those filters |
| Chart page | https://anilist.co/search/manga/popular (also /trending; anime or manga) | the same list as Charts mode (popular or trending) |
| Top 100 | https://anilist.co/search/anime/top-100 | the 100 best-scored titles |
| Seasonal chart | https://anilist.co/search/anime/this-season (also /next-season; anime only) | popular titles of the current (or next) season |
Forms that point at a record already covered above need no separate example, because they resolve to the same record as the id-only link: a trailing /<slug> or slash (https://anilist.co/anime/154587/Sousou-no-Frieren/), a sub-page such as .../manga/30013/One-Piece/characters or /staff, the www host, http, and a trailing query string. Listing links take their anime or manga type from the link itself. Search options the actor does not read (for example tags, episodes) are ignored with a warning in the log, and an unknown chart name (for example /search/anime/bogus) is skipped with a warning. Character, staff, studio and user pages are not scraped: each one is skipped with a warning. A warning is also logged when the link says anime or manga but AniList reports the other type.
Limits and adult titles for listing links: Max records and Max pages apply to each pasted search or chart link separately. Listing links respect the Include adult media setting like Search and Charts modes (adult titles are excluded by default); pasted media links and ids are returned either way. A listing link with page=2 or later starts in the middle of the list, so that run cannot tell which earlier records are gone: with Incremental mode it never produces EXPIRED rows. The default prefill puts one example of each listing shape next to the two media links, so a run started from the untouched prefill returns up to Max records for each of the four listing links plus the two media records; trim the list for a smaller run.
Behaviour change: in URL mode with the URLs field left untouched, the actor now scrapes one anime and one manga example (https://anilist.co/anime/154587 and https://anilist.co/manga/30013) instead of nothing. Send "urls": [] to scrape no links. An API call that omits the field gets just those two media links; the Console form is prefilled with those two plus one example of each listing shape.
Daily monitoring of a trending chart, changes only:
{"mode": "charts","chartKind": "TRENDING","incrementalMode": true,"stateKey": "trending-anime-watch"}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/anilist-anime-manga-scraper").call(run_input={"mode": "search", "searchTerms": ["sample title"], "maxMedia": 10})for media in client.dataset(run["defaultDatasetId"]).iterate_items():print(media["titleRomaji"], media["averageScore"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/anilist-anime-manga-scraper').call({ mode: 'search', searchTerms: ['sample title'], maxMedia: 10 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
How Max records and Max pages shape a run
Max records (maxMedia) stops the run once this many records have been returned (0 = no limit; default 25; the input accepts at most 100000). Max pages (maxPages) caps how many pages are walked per search term or chart (50 records per page; 0 = no limit, the default). A search with several terms walks each term as its own scope, so a low Max pages value limits every term individually, not the run as a whole. In URL mode both limits apply to each pasted search or chart link separately, while every pasted media link or id is looked up and returned, so the size of your list sets the size (and cost) of the run.
Include adult media (includeAdult) switches the search and chart filter rather than widening it: with it on, search and chart results contain adult titles only. In URL mode the same setting filters pasted search and chart links, but a pasted media link or id to an adult title is returned either way.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset ID and the actor skips everything already collected there, so you don't pay twice. - Incremental mode (
incrementalMode) is for running the same search, chart or URL list again and again (for example daily) and getting only what changed. Each record is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEARED, orEXPIRED(only after a run that was not resumed, hit no cap and reached the end of every tracked term, chart or pasted listing link (a listing link that starts at page 2 or later never qualifies), and only withemitExpiredon; see the tips below).stateKeynames or shares the stored state. A record counts as changed when any output field differs from the stored copy, exceptpopularity,favourites,trending,rankingsand the tagrankpercentages: those community counters and chart positions move almost daily, so they stay in the output but never triggerUPDATEDand are never listed inchangedFields. UseignoreFieldsForChangesto exclude further fields (dotted names reach into nested values). Existing baselines are re-checked with the same exclusions, so upgrading causes no one-time wave ofUPDATEDrows. With Incremental mode off, output is exactly as before.
Tip: Turning on Emit expired does not cap EXPIRED rows at Max records. Max records only stops the live search or chart walk; once that walk finishes cleanly, with no cap hit and every tracked term or chart fully read, every previously tracked record that no longer appears is written as EXPIRED in that same run, and that batch is not limited by Max records. On a broad or long-running monitoring scope this can occasionally return far more rows than Max records specifies. Keep the tracked search terms narrow, or split monitoring across separate State key values, to keep any one cleanup batch smaller.
Tip: Combining Resume with Incremental mode on the same run correctly skips re-pushing (and re-billing) records the resumed run already collected, but those skipped records are not added to the incremental baseline that gets saved. The next scheduled incremental run, without Resume, does not recognize any of them that were not already in the baseline from an earlier incremental run, and will emit and bill them again as NEW. If you use Resume to catch up a large pull, expect one extra NEW pass on the following incremental run, or start incremental monitoring from a plain run (no Resume) so the baseline is complete from the first pass.
Tip: With Emit expired on, a record can occasionally be marked EXPIRED even though it still exists. In search and charts modes, a result page that comes back empty after the first page of a term, or an empty first page of a chart, is treated as the end of that list, so the records that would have followed are returned as EXPIRED and billed as EXPIRED rows; the next run that finds such a record again returns and bills it as REAPPEARED. Cases that cannot prove a record is gone block EXPIRED for the whole run instead, so nothing is tombstoned or billed as EXPIRED: in URL mode a pasted listing link that starts at page 2 or later (it cannot see the earlier records), a link whose lookup fails (for example a refused or timed-out request), and a keyword term whose first page stays empty on every retry. If you rely on EXPIRED rows, confirm a record's absence on a second run before acting on it.
Output views
The dataset has three views in the Console. Media is the overview table (titles, format, status, scores, genres, studios). Detail adds the long-form fields (synopsis, tags, rankings, trailer, external links). Changes shows changeType, changedFields, firstSeenAt and lastSeenAt for Incremental runs. A run that covers several scopes (several search terms, for example) also writes a small OUTPUT summary to the key-value store.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search, charts, or url. |
mediaType | string | ANIME | ANIME or MANGA. Applies to search, charts and URL modes. |
searchTerms | array | ["frieren"] | Keywords to search for (search mode). Each term is searched separately; results are merged and de-duplicated. |
chartKind | string | TRENDING | TRENDING, POPULAR, TOP_RATED, or FAVOURITES (charts mode). |
urls | array | one anime and one manga sample link | AniList media links, bare numeric ids, or search and chart links (URL mode). |
maxMedia | integer | 25 | Stop after this many media records (0 = no limit). |
maxPages | integer | 0 | Cap on pages walked per search term or chart (50 records per page; 0 = no limit). |
includeAdult | boolean | false | Off by default; adult media is excluded. When on, results are adult titles only (use adultContent to include both). |
adultContent | string | unset | exclude, include (adult and non-adult together) or only. Unset follows includeAdult. |
format | array | unset | Keep only these formats (TV, TV_SHORT, MOVIE, SPECIAL, OVA, ONA, MUSIC, MANGA, NOVEL, ONE_SHOT); any of them matches. Search and charts. |
status | array | unset | Keep only these statuses (FINISHED, RELEASING, NOT_YET_RELEASED, CANCELLED, HIATUS). |
season | string | unset | Anime season: WINTER, SPRING, SUMMER or FALL. |
seasonYear | integer | unset | Anime season year, for example 2025. |
genres | array | unset | Keep only titles that have all of the selected genres. |
sort | string | unset | POPULARITY_DESC, SEARCH_MATCH, SCORE_DESC, TRENDING_DESC, START_DATE_DESC or FAVOURITES_DESC. Unset keeps the default order (search: best match; charts: the chart ranking). |
resumeFromRunId | string | (none) | Paste a previous run ID or dataset ID to continue a large pull without returning items already collected there. |
incrementalMode | boolean | false | Turn this on for daily or recurring monitoring. The first run returns every matching record as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED records. |
stateKey | string | (none) | Optional. Name this monitoring campaign to keep its state stable, or deliberately share state across differently configured runs. |
emitUnchanged | boolean | false | Off by default. Also return records that have not changed since the last run, marked UNCHANGED. Returns, and bills, extra rows you already have. |
emitExpired | boolean | false | Off by default. Also return records that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search. |
ignoreFieldsForChanges | array | [] | Extra field names to leave out of change detection (incremental mode only). popularity, favourites, trending, rankings and tags.rank are always left out. |
mcpConnectors | array | (none) | Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Leave empty to skip; never changes the dataset output. |
notionParentPageUrl | string | (none) | Notion connector only: URL or id of the page under which item pages are created. Ignored by other connectors. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
proxyConfiguration | object | Apify Proxy | Connection used for every request. Works on every proxy plan. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"id": 999001,"idMal": 888001,"url": "https://anilist.co/anime/999001","titleRomaji": "Sample Romaji Title","titleEnglish": "Sample English Title","titleNative": "サンプルタイトル","format": "TV","status": "FINISHED","episodes": 24,"chapters": null,"volumes": null,"durationMin": 23,"averageScore": 78,"meanScore": 77,"popularity": 45000,"favourites": 9000,"genres": ["Fantasy", "Adventure"],"countryOfOrigin": "JP","isAdult": false,"description": "A sample synopsis describing the plot in a few sentences.","season": "SPRING","seasonYear": 2025,"startDate": "2025-04-01","endDate": "2025-09-20","studios": ["Sample Studio"],"nextAiringEpisode": null,"nextAiringAt": null,"coverImage": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/sample-id.jpg","bannerImage": "https://s4.anilist.co/file/anilistcdn/media/anime/banner/sample-id.jpg"}
Plan Requirement
Measured: AniList's data API answered ordinary Apify datacenter connections as well as residential ones with the same data, so no residential plan is needed. The default Apify Proxy setting needs a plan that includes Apify Proxy. If the account has no proxy access, the run stops with: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required". If the default connection is unavailable the run falls back to a backup connection and logs: "Served over the backup connection (the default connection was unavailable)." If that also cannot load pages, the run fails with a message that residential proxies are unavailable on this run and asks you to upgrade or supply your own proxy URLs. Supplying your own proxy URLs in the Proxy configuration works on any plan.
FAQ
How much does it cost?
Billing has two parts: a dataset item event for each record written to the dataset, and an actor start event for each run (scaled per GB of memory). The Pricing tab shows the current rates. Records suppressed as UNCHANGED in Incremental mode are not written and not billed. Use Max records to cap the cost of any run.
Is it legal to scrape AniList?
This actor collects only publicly available anime and manga catalog data. You are responsible for how you use it: follow AniList's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Scores, popularity and other metadata are catalog facts, but cover art, banner images and synopses may carry third-party rights.
Can I get only new or changed titles on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and reappeared records, and unchanged ones are not billed.
What's the difference between Resume and Incremental mode?
Resume (resumeFromRunId) continues ONE specific interrupted run using its run or dataset id, so you don't pay twice for what that run already collected. Incremental mode is for running the SAME search, chart or URL list again and again (daily, for example) and getting only what changed since the previous run. They can be combined, but see the tip under "Resume and recurring updates": combining them does not fold the resumed records into the incremental baseline, so plan for one extra NEW pass on the following incremental run.
Why did an Emit expired run return more records than Max records?
Max records caps the live search or chart walk, not the EXPIRED batch written at the end of that run. Once the walk finishes without hitting any cap, every previously tracked record that no longer appears is written as EXPIRED in the same run, uncapped. Narrow the tracked search terms, or split monitoring across separate State key values, to keep any one cleanup batch smaller.
Why did my run fail instead of returning an empty dataset?
If no results page can be loaded, the run stops with a clear message so "nothing could be read" is never confused with a genuinely empty search. A pure connection failure reads: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later." Run it again in a few minutes, or adjust the Proxy configuration in the input. If AniList itself reports its API as temporarily disabled or rate limits the run, that is an outage on their side; retry later. A search that honestly matches nothing (a real term with no results) still succeeds with zero records.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
🔗 More scrapers you might like
Pair this actor with these related scrapers from the same team:
| 🧩 MyAnimeList Scraper Scrape MyAnimeList anime and manga by keyword, ranking chart or URL. Extract titles... | 🧩 GoodShort Scraper Scrape the GoodShort short-drama catalog: titles with exact views, follows, genres and... |
| 🧩 ReelShort Scraper Scrape the ReelShort vertical short-drama catalog: titles, synopses, themes and full tag... | 🧩 Pocket Casts Podcast Scraper Scrape Pocket Casts podcast data, including listener ratings, full episode archives... |
| 🧩 Deezer Scraper Scrape Deezer by keyword or URL. Extract tracks, albums, artists, playlists, lyrics... | 🧩 WEBTOON Scraper Scrape the WEBTOON catalog into structured data. Extract series, genres, rankings and... |
💬 Support
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.