     [Blog](https://scrapfly.io/blog)   /  [python](https://scrapfly.io/blog/tag/python)   /  [How to Scrape IMDb Data, Ratings, and Featured Reviews](https://scrapfly.io/blog/posts/how-to-scrape-imdb)   # How to Scrape IMDb Data, Ratings, and Featured Reviews

 by [Mohab Yousry](https://scrapfly.io/blog/author/mohab-yousry-9396552a) Aug 13, 2026 16 min read [\#python](https://scrapfly.io/blog/tag/python) [\#scrapeguide](https://scrapfly.io/blog/tag/scrapeguide) 

 [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-imdb "Share on LinkedIn") [  ](https://x.com/intent/tweet?url=https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-imdb&text=How%20to%20Scrape%20IMDb%20Data%2C%20Ratings%2C%20and%20Featured%20Reviews "Share on X") [  ](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-imdb "Share on Facebook")    

 

 

Summarize this article with

 [  ](https://chat.openai.com/?q=Summarize%20this%20article%20and%20explain%20how%20Scrapfly%20helps%20me%20scrape%20any%20website%20at%20scale%20and%20bypass%20anti-bot%20systems%20for%20my%20use%20case%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-imdb) [  ](https://claude.ai/new?q=Summarize%20this%20article%20and%20explain%20how%20Scrapfly%20helps%20me%20scrape%20any%20website%20at%20scale%20and%20bypass%20anti-bot%20systems%20for%20my%20use%20case%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-imdb) [  ](https://x.com/i/grok?text=Summarize%20this%20article%20and%20explain%20how%20Scrapfly%20helps%20me%20scrape%20any%20website%20at%20scale%20and%20bypass%20anti-bot%20systems%20for%20my%20use%20case%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-imdb) [  ](https://www.perplexity.ai/search/new?q=Summarize%20this%20article%20and%20explain%20how%20Scrapfly%20helps%20me%20scrape%20any%20website%20at%20scale%20and%20bypass%20anti-bot%20systems%20for%20my%20use%20case%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-imdb) [  ](https://www.google.com/search?udm=50&aep=11&q=Summarize%20this%20article%20and%20explain%20how%20Scrapfly%20helps%20me%20scrape%20any%20website%20at%20scale%20and%20bypass%20anti-bot%20systems%20for%20my%20use%20case%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-imdb) 



         

IMDb now returns an AWS WAF challenge to a plain title-page request. Once the page is fetched, CSS selectors are still the wrong layer: in the Reddit example that returned 25 watchlist titles, the full list was already present in `__NEXT_DATA__`.

This guide extracts movie and TV metadata, ratings, discovery data, and the featured reviews available without signing in.



[**IMDb scraper**github.com/scrapfly/scrapfly-scrapers/tree/main/imdb-scraper](https://github.com/scrapfly/scrapfly-scrapers/tree/main/imdb-scraper)

## Key Takeaways

- IMDb sits behind AWS WAF. In our 2026-08-13 check, a plain request to the first title page returned HTTP 202 with `x-amzn-waf-action: challenge`.
- On the title-page types covered by the repo, headline metadata and the aggregate rating live in an `application/ld+json` block. Deeper fields like runtime and box office live in the page's own `__NEXT_DATA__` payload, the JSON blob Next.js uses to hydrate the page client-side.
- The canonical repo uses `asp=True`, `country="US"`, `proxy_pool="public_residential_pool"`, and `render_js=True` as its baseline.
- IMDb now requires sign-in for the full review corpus. Logged-out responses varied in our 2026-08-13 checks: one `/reviews/` render showed five featured cards, while another showed only the sign-in wall. The repo therefore reads the small `featuredReviews` set from the title page.
- IMDb's terms prohibit website scraping without express consent. Use its datasets for permitted personal, non-commercial metadata, and use IMDb's licensed products or written permission for fields those datasets do not cover.

**Get web scraping tips in your inbox**Trusted by 100K+ developers and 30K+ enterprises. Unsubscribe anytime.







## What Data Can You Scrape From IMDb?

The public-page implementation in this guide covers five data groups: title and TV metadata, ratings, top-billed cast and crew, a small featured-review sample, and discovery surfaces such as search, charts, and person pages. Fetch access is protected by AWS WAF, and the full review corpus requires sign-in.

| Data type | Fields | Where it lives | Typical use case |
|---|---|---|---|
| Metadata | name, year, title type, genres, plot, content rating, keywords, runtime, box office | JSON-LD plus `__NEXT_DATA__` | Catalog enrichment |
| Ratings | aggregate rating value, vote count | JSON-LD | Ratings dataset |
| Cast and crew | top-billed actors, directors | JSON-LD `actor` and `director` arrays | Catalog enrichment |
| Featured reviews | author, rating, summary, text, spoiler flag | Title-page `__NEXT_DATA__.featuredReviews` | Small-sample review inspection |
| Discovery | title search, Top 250 chart, filmographies | `__NEXT_DATA__` on `/find`, `/chart/<type>`, and `/name/<nm>` pages | Title discovery and tconst resolution |

Headline metadata, ratings, and top-billed cast sit in JSON-LD. Runtime, box office, title-page featured reviews, search, charts, and person data sit in `__NEXT_DATA__`.

Choose the smallest surface that fits the job. A ratings dataset needs JSON-LD. Title enrichment uses both title-page payloads. Review analysis is limited to the handful of featured reviews exposed without signing in.

Before any parser runs, the fetch must clear IMDb's AWS WAF challenge.



## What Protects IMDb, and How to Get In

IMDb currently returns an AWS WAF challenge to a plain title-page request. The Scrapfly Web Scraping API with `asp=True` handles that shield for the public pages used in this guide, without requiring you to maintain the challenge flow.

In a 2026-07-09 Scrapfly run, IMDb served a Hashcash SHA-2 proof-of-work challenge (`aws_waf`). ASP escalated to a residential browser session, returned HTTP 200, and billed 30 credits. A plain request still receives the AWS WAF challenge as of 2026-08-13.

### Why BeautifulSoup and requests tutorials break on IMDb

Two things break the SERP's Top 250 tutorials.

- They parse CSS classes like `li.ipc-metadata-list-summary-item`, `h3.ipc-title__text`, and `span.ipc-rating-star--rating`, and IMDb rotates those classes as it re-skins its markup. A GeeksforGeeks tutorial last updated June 18, 2026, still teaches exactly this pattern against the Top 250 page, which means it breaks the moment IMDb ships a new class name.
- Access and parsing fail independently. In our 2026-08-13 check, a plain title-page request hit AWS WAF immediately. After a successful fetch, parsing only visible CSS cards can still miss records stored in `__NEXT_DATA__`.

A developer on [r/learnpython](https://www.reddit.com/r/learnpython/comments/1fz1obs/help_needed_with_imdb_scraper/) got only 25 names from a hundred-plus-title watchlist. The saved response contained the full page, and the OP fixed the scraper by reading `__NEXT_DATA__`. That case was a parsing and data-layer problem, not evidence of AWS WAF or a request-count limit.

### Fetch an IMDb page with the Web Scraping API

The fix is a config change, not a bypass you build and maintain yourself. The confirmed `imdb-scraper` reference implementation runs every request through this exact base config.

python```python
from scrapfly import ScrapflyClient, ScrapeConfig

client = ScrapflyClient(key="YOUR_API_KEY")

BASE_CONFIG = {
    "asp": True,
    "country": "US",
    "proxy_pool": "public_residential_pool",
    "render_js": True,
}

config = ScrapeConfig(
    url="https://www.imdb.com/title/tt0111161/",
    **BASE_CONFIG,
)

response = client.scrape(config)
print(response.scrape_result["status"])  # 200
```



`asp=True` handles the AWS WAF challenge and any browser escalation IMDb demands. The reference scraper adds two more settings on top, both costing extra credits.

- `proxy_pool="public_residential_pool"`, a residential proxy pool.
- `render_js=True`, full browser rendering.

Treat `asp=True` alone as fine for a quick check, and add the other two once you are running at real volume. IMDb is a Next.js app, so its data sits embedded in the markup rather than scattered across DOM classes, which is what the next section extracts.

For the full parameter reference, see the [Scrapfly Web Scraping API](https://scrapfly.io/products/web-scraping-api).

With a page reliably in hand, the next question is where inside that page the actual movie data lives.



## How to Extract IMDb Movie Data

Parse the JSON-LD `Movie` block for headline metadata, ratings, cast, and directors, then read the page's own `__NEXT_DATA__` script for runtime and box office. Do not fight CSS selectors that IMDb changes on its own schedule.

### Parse the JSON-LD movie schema

The IMDb title page tested here ships an `application/ld+json` block describing the title. For `tt0111161`, the parsed record includes the title, R content rating, aggregate rating, top-billed actors, director, and keywords. In our 2026-08-13 live check, IMDb showed 9.3 over 3,223,095 votes; the vote count is volatile. It survives IMDb re-skinning its CSS because JSON-LD is a schema.org contract, not a styling hook.

python```python
import json

# response is the ScrapeApiResponse from client.scrape().
def parse_ld_json(response, types: tuple) -> dict:
    for script in response.selector.css('script[type="application/ld+json"]::text'):
        data = json.loads(script.get() or "{}")
        if data.get("@type") in types:
            return data
    return {}

ld = parse_ld_json(response, ("Movie", "TVSeries", "TVEpisode", "TVMovie", "TVMiniSeries", "VideoGame"))
rating = ld.get("aggregateRating") or {}

movie = {
    "id": ld["url"].rstrip("/").split("/")[-1],
    "name": ld.get("name"),
    "type": ld.get("@type"),
    "description": ld.get("description"),
    "content_rating": ld.get("contentRating"),
    "genre": ld.get("genre"),
    "cast": [a.get("name") for a in ld.get("actor", [])],
    "directors": [d.get("name") for d in ld.get("director", [])],
    "keywords": (ld.get("keywords") or "").split(","),
    "rating_value": rating.get("ratingValue"),
    "rating_count": rating.get("ratingCount"),
}
print(movie)
```



Note that `actor` only carries the top-billed names IMDb chooses to expose in the schema, three for Shawshank Redemption, not the full cast list.

### Go deeper with `__NEXT_DATA__` for runtime and box office

Runtime and box office live in the page's `__NEXT_DATA__` script instead, under `props.pageProps.mainColumnData` for box office and `props.pageProps.aboveTheFoldData.runtime.seconds` for runtime.



python```python
def parse_next_data(response) -> dict:
    raw = response.selector.css("script#__NEXT_DATA__::text").get()
    return json.loads(raw) if raw else {}


def parse_money(node):
    if not node:
        return None
    return node.get("total") or node.get("budget")


page = parse_next_data(response).get("props", {}).get("pageProps", {})
main = page.get("mainColumnData") or {}
runtime = ((page.get("aboveTheFoldData") or {}).get("runtime") or {}).get("seconds")

movie["runtime_minutes"] = runtime // 60 if runtime else None
movie["box_office"] = {
    "budget": parse_money(main.get("productionBudget")),
    "gross_us_canada": parse_money(main.get("lifetimeGross")),
    "gross_worldwide": parse_money(main.get("worldwideGross")),
    "opening_weekend": parse_money((main.get("openingWeekendGross") or {}).get("gross")),
}
```



In our 2026-08-13 check, `tt0111161` resolved to a 142-minute runtime, a $25,000,000 budget, and a $29,424,909 worldwide gross. The money fields remain nested `{amount, currency}` objects rather than flat numbers.

Cinemagoer now focuses on local copies of IMDb's non-commercial TSV datasets. Its README says website parsing moved to CinemagoerNG after IMDb added the WAF in April 2026. The project is GPL-2.0-or-later, so copying or distributing its code requires compliance with that license; review compatibility before vendoring it.

With title-level extraction covered, the harder target is reviews, and the honest answer there has changed recently.



## How to Scrape Featured IMDb Reviews

The full review corpus is sign-in gated. In two logged-out checks on 2026-08-13, `/title/<tt>/reviews/` varied between five featured cards and only the sign-in wall, so do not build a scraper around that route. The canonical repo reads the small `featuredReviews` set from the title page's `__NEXT_DATA__` instead.

### Where featured reviews actually live

The scraper re-fetches the title page and reads `props.pageProps.mainColumnData.featuredReviews.edges`, a curated shortlist rather than the full set. Scraping `tt0111161` this way returned five reviews.



python```python
import html as html_lib
import re

def parse_reviews(response) -> list:
    page = parse_next_data(response).get("props", {}).get("pageProps", {})
    edges = ((page.get("mainColumnData") or {}).get("featuredReviews") or {}).get("edges") or []
    reviews = []
    for edge in edges:
        node = edge.get("node") or {}
        if not node.get("id"):
            continue
        author = node.get("author") or {}
        raw = ((node.get("text") or {}).get("originalText") or {}).get("plaidHtml") or ""
        text = html_lib.unescape(raw)
        text = re.sub(r"<br\s*/?>", "\n", text, flags=re.I)
        text = re.sub(r"<[^>]+>", "", text).strip() or None
        reviews.append({
            "id": node["id"],
            "author": (author.get("username") or {}).get("text"),
            "summary": (node.get("summary") or {}).get("originalText"),
            "text": text,
            "rating": node.get("authorRating"),
            "spoiler": bool(node.get("spoiler")),
        })
    return reviews
```



The committed 2026-07-16 result contains five records, including `rw6606154`, with review HTML converted to plain text. Featured selection and order are volatile: a 2026-08-13 live title page showed `rw3118520` first.

### The sign-in wall

The logged-out page exposes no supported path to paginate the full review corpus and directs readers to sign in. The canonical repo intentionally stops at the featured set. For more review data, evaluate IMDb's licensed User Reviews product and confirm its coverage, or obtain express permission for authenticated collection.

Watch for these failure modes in a review scraper built against the current site.

- Requesting `/title/<tt>/reviews/` and getting a sign-in wall instead of review markup.
- Treating the five to ten featured reviews as the complete set when reporting results.
- Assuming an `after` or `endCursor` pagination parameter still works against a page that no longer exposes one.

Once the review limitation is priced into your plan, the same access and extraction pattern extends to discovering which titles to scrape in the first place.



## How to Scrape IMDb Search, Charts, and Filmographies

Use IMDb's title search and the Top 250 chart to discover title IDs, known as tconst values, and use person pages to pull filmographies, then enrich each discovered ID with the extraction path covered earlier. All three surfaces hydrate through the same `__NEXT_DATA__` pattern as the title page.

Discovering and enriching multiple IMDb title IDs is a two-step workflow.

- **Discovery.** Resolve a search term, chart entry, or person page into a list of tconst IDs.
- **Enrichment.** Fetch each known ID through the Web Scraping API and parse the embedded JSON-LD and `__NEXT_DATA__`.

### Search

`https://www.imdb.com/find/?q=<query>&s=tt` hydrates its results into `props.pageProps.titleResults.results`, where each entry's `listItem` carries the tconst, title, type, year, and rating summary.



python```python
from urllib.parse import quote_plus

def parse_search(response) -> list:
    page = parse_next_data(response).get("props", {}).get("pageProps", {})
    results = []
    for entry in (page.get("titleResults") or {}).get("results", []):
        item = entry.get("listItem") or {}
        title_id = item.get("titleId")
        if not title_id:
            continue
        rating = item.get("ratingSummary") or {}
        results.append({
            "id": title_id,
            "name": item.get("titleText"),
            "type": (item.get("titleType") or {}).get("id"),
            "year": item.get("releaseYear"),
            "rating_value": rating.get("aggregateRating"),
            "rating_count": rating.get("voteCount"),
        })
    return results

def fetch_imdb(url: str):
    return client.scrape(ScrapeConfig(url=url, **BASE_CONFIG))


url = f"https://www.imdb.com/find/?q={quote_plus('shawshank')}&s=tt"
search_results = parse_search(fetch_imdb(url))
print(search_results[:3])
```



Scrapfly

#### Scale your web scraping effortlessly

Scrapfly handles proxies, browsers, and anti-bot bypass — so you can focus on data.

[Try Free →](https://scrapfly.io/register)A live search for "shawshank" returns `tt0111161` first, `type: "movie"`, `year: 1994`, `rating_value: 9.3`, alongside unrelated titles like `tt0293927`, a 2001 TV movie about the filming.

### Top 250 chart

`https://www.imdb.com/chart/top/` hydrates into `props.pageProps.pageData.chartTitles.edges`, and each edge carries its own `currentRank` alongside the same rating summary shape as search.



python```python
def parse_chart(response) -> list:
    page = parse_next_data(response).get("props", {}).get("pageProps", {})
    edges = ((page.get("pageData") or {}).get("chartTitles") or {}).get("edges") or []
    entries = []
    for edge in edges:
        node = edge.get("node") or {}
        title_id = node.get("id")
        if not title_id:
            continue
        rating = node.get("ratingsSummary") or {}
        entries.append({
            "rank": edge.get("currentRank"),
            "id": title_id,
            "name": (node.get("titleText") or {}).get("text"),
            "rating_value": rating.get("aggregateRating"),
            "rating_count": rating.get("voteCount"),
            "year": (node.get("releaseYear") or {}).get("year"),
        })
    return entries

chart = parse_chart(fetch_imdb("https://www.imdb.com/chart/top/"))
print(chart[:3])

```



A 2026-08-13 live fetch returned all 250 entries, with `tt0111161` at rank 1 and 9.3. Rank 250 was `tt0077711`, Autumn Sonata, at 8.1; chart positions and scores are volatile.

### Person pages and filmographies

`https://www.imdb.com/name/<nm>/` carries biography fields under `aboveTheFold` and filmography credits under `mainColumnData.released.edges`, each edge grouped by category (Actor, Producer, Director) with its own nested `credits.edges`.



python```python
def parse_person(response) -> dict:
    page = parse_next_data(response).get("props", {}).get("pageProps", {})
    above = page.get("aboveTheFold") or {}
    main = page.get("mainColumnData") or {}

    filmography = []
    for group in (main.get("released") or {}).get("edges") or []:
        node = group.get("node") or {}
        category = (node.get("grouping") or {}).get("text")
        for credit in (node.get("credits") or {}).get("edges", []):
            title = (credit.get("node") or {}).get("title") or {}
            if title.get("id"):
                filmography.append({
                    "id": title["id"],
                    "name": (title.get("titleText") or {}).get("text"),
                    "type": (title.get("titleType") or {}).get("text"),
                    "category": category,
                })

    return {
        "name": (above.get("nameText") or {}).get("text"),
        "bio": ((above.get("bio") or {}).get("text") or {}).get("plainText"),
        "birth_date": (above.get("birthDate") or {}).get("date"),
        "professions": [
            p["category"]["text"] for p in above.get("primaryProfessions") or []
            if (p.get("category") or {}).get("text")
        ] or None,
        "filmography": filmography or None,
    }

person = parse_person(fetch_imdb("https://www.imdb.com/name/nm0000209/"))
print(person)

```



Scraping `nm0000209` returns Tim Robbins, born 1958-10-16, professions `["Actor", "Producer", "Director"]`, and a filmography that includes his `Actor` credit on Castle Rock (`tt6548228`) and Dark Waters (`tt9071322`).

The loop below fetches known title IDs and returns a compact parsed row from the same JSON-LD helper used earlier. Extend that row with `parse_next_data()` fields when you need runtime or box office.



python```python
from scrapfly import ScrapflyClient, ScrapeConfig

client = ScrapflyClient(key="YOUR_API_KEY")
BASE_CONFIG = {"asp": True, "country": "US", "proxy_pool": "public_residential_pool", "render_js": True}

tconst_ids = ["tt0111161", "tt0068646", "tt0071562"]

records = []
for tconst in tconst_ids:
    response = client.scrape(ScrapeConfig(
        url=f"https://www.imdb.com/title/{tconst}/",
        **BASE_CONFIG,
    ))
    ld = parse_ld_json(response, ("Movie", "TVSeries", "TVEpisode", "TVMovie", "TVMiniSeries", "VideoGame"))
    rating = ld.get("aggregateRating") or {}
    records.append({
        "id": tconst,
        "name": ld.get("name"),
        "type": ld.get("@type"),
        "rating_value": rating.get("ratingValue"),
        "rating_count": rating.get("ratingCount"),
    })

print(records)

```



Once you have parsed title records and featured reviews, you can shape them for analysis.

## How to Structure IMDb Reviews for Analysis

Load the parsed review objects into a pandas DataFrame for a quick, local pass at rating trends, or use the Scrapfly Extraction API when you want normalized, schema-consistent fields, or sentiment tags, across a large multi-title corpus.

A DataFrame is the right tool when you are analyzing one title's featured reviews on your own machine. The [Extraction API](https://scrapfly.io/products/extraction-api) is useful when you are normalizing the same small featured-review sample across many titles and need consistent fields or sentiment tags. Either way, remember the input is a handful of featured reviews per title, not the full corpus.



python```python
import pandas as pd

reviews = [
    {"id": "rw6606154", "author": "Sleepin_Dragon", "summary": "An incredible movie. One that lives with you.", "rating": 10, "spoiler": False},
    {"id": "rw1221355", "author": "EyeDunno", "summary": "Don't Rent Shawshank.", "rating": 10, "spoiler": False},
    {"id": "rw1288098", "author": "kaspen12", "summary": "A classic piece of unforgettable film-making.", "rating": 10, "spoiler": True},
]

df = pd.DataFrame(reviews)
df["captured_at"] = pd.Timestamp.utcnow()
df.to_csv("imdb_reviews.csv", index=False)
print(df.head())
```



Point the output at the use case that matters to you, rating-trend tracking over time, review sentiment analysis on the available sample, or comparing reception across a franchise or catalog. Just size your conclusions to a five-review sample rather than treating it as a representative slice of a title's full audience.

IMDb's terms determine which collection path you can use.



## FAQ

Does IMDb have an API?Yes. IMDb offers GraphQL-backed commercial products through AWS Data Exchange and daily non-commercial TSV datasets for personal use. The TSV files do not include reviews; IMDb lists User Reviews as a commercial add-on.







How do I get all of a title's reviews?You cannot get the full corpus through the logged-out path documented here. IMDb directs logged-out users to sign in, and public responses expose at most featured cards. This scraper intentionally returns the title page's `featuredReviews` set.







Do I need a headless browser to scrape IMDb?Effectively yes. The reference scraper pairs `asp=True` with `render_js=True` and a residential proxy as its baseline, mainly to clear the shield reliably, not because the fields themselves need script execution to appear.







Is cinemagoer enough?For metadata and ratings from IMDb's non-commercial TSV datasets, often yes. Cinemagoer no longer claims current webpage parsing; its maintainers direct that job to CinemagoerNG, where you provide the fetch function. Neither path gives logged-out access to the full review corpus.







Is it legal to scrape IMDb?IMDb's Help Center allows limited non-commercial use only from its provided datasets and says not to use data mining, robots, screen scraping, or similar extraction tools on the website. Prefer the official datasets for bulk metadata, avoid redistribution, and check the terms and counsel for commercial use.









## Summary

Scraping IMDb is a shield problem plus a narrower review surface than older guides describe. Clear AWS WAF with `asp=True`, `render_js=True`, and a residential proxy because a plain request currently hits the challenge on the first fetch, then extract headline fields from JSON-LD and pull runtime, box office, and featured reviews from the same page's `__NEXT_DATA__`. Enrich a title list via search, chart, and person pages using that same fetch pattern.

The [Scrapfly Web Scraping API](https://scrapfly.io/products/web-scraping-api) clears that shield for you, and the [Extraction API](https://scrapfly.io/products/extraction-api) structures the result once you are running this across more than a handful of titles. For permitted non-commercial bulk metadata rather than reviews, the official datasets at `datasets.imdbws.com` remain the right call.



### Web Scraping API

Scrape any website with our powerful API. Anti-bot bypass, JavaScript rendering, and rotating proxies built-in.



[Try Web Scraping API](https://scrapfly.io/docs/scrape-api/getting-started)



Legal Disclaimer and PrecautionsThis tutorial covers popular web scraping techniques for education. Interacting with public servers requires diligence and respect:

- Do not scrape at rates that could damage the website.
- Do not scrape data that's not available publicly.
- Do not store PII of EU citizens protected by GDPR.
- Do not repurpose *entire* public datasets which can be illegal in some countries.

Scrapfly does not offer legal advice but these are good general rules to follow. For more you should consult a lawyer.

 

   [  Add as a preferred source ](https://google.com/preferences/source?q=scrapfly.io) Table of Contents















 

  Table of Contents- [Key Takeaways](#key-takeaways)
- [What Data Can You Scrape From IMDb?](#what-data-can-you-scrape-from-imdb)
- [What Protects IMDb, and How to Get In](#what-protects-imdb-and-how-to-get-in)
- [Why BeautifulSoup and requests tutorials break on IMDb](#why-beautifulsoup-and-requests-tutorials-break-on-imdb)
- [Fetch an IMDb page with the Web Scraping API](#fetch-an-imdb-page-with-the-web-scraping-api)
- [How to Extract IMDb Movie Data](#how-to-extract-imdb-movie-data)
- [Parse the JSON-LD movie schema](#parse-the-json-ld-movie-schema)
- [Go deeper with \_\_NEXT\_DATA\_\_ for runtime and box office](#go-deeper-with-next-data-for-runtime-and-box-office)
- [How to Scrape Featured IMDb Reviews](#how-to-scrape-featured-imdb-reviews)
- [Where featured reviews actually live](#where-featured-reviews-actually-live)
- [The sign-in wall](#the-sign-in-wall)
- [How to Scrape IMDb Search, Charts, and Filmographies](#how-to-scrape-imdb-search-charts-and-filmographies)
- [Search](#search)
- [Top 250 chart](#top-250-chart)
- [Person pages and filmographies](#person-pages-and-filmographies)
- [How to Structure IMDb Reviews for Analysis](#how-to-structure-imdb-reviews-for-analysis)
- [FAQ](#faq)
- [Summary](#summary)
 
    Join the Newsletter  Get monthly web scraping insights 

 

  



Scale Your Web Scraping

Anti-bot bypass, browser rendering, and rotating proxies, all in one API. Start with 1,000 free credits.

  No credit card required  1,000 free API credits  Anti-bot bypass included 

 [Start Free](https://scrapfly.io/register) [View Docs](https://scrapfly.io/docs/onboarding) 

 Not ready? Get our newsletter instead. 

 

 ## Related Articles

 [  

 http nodejs 

### Axios vs Fetch: Which HTTP Client to Choose in JS?

Explore the differences between Fetch and Axios - two essential HTTP clients in JavaScript - and discover which is best ...

 

 ](https://scrapfly.io/blog/posts/axios-vs-fetch) [  

 python data-parsing 

### Ultimate Guide to JSON Parsing in Python

Learn JSON parsing in Python with this ultimate guide. Explore basic and advanced techniques using json, and tools like ...

 

 ](https://scrapfly.io/blog/posts/how-to-use-python-to-parse-json) [     

 python hidden-api 

### How to Scrape Google Play App Reviews and Data

Scrape Google Play app metadata, ratings, and the full review set with Python, past the few-hundred-review ceiling the f...

 

 ](https://scrapfly.io/blog/posts/how-to-scrape-google-play-app-reviews-and-data) 

  



   



 Scale your web scraping effortlessly, **1,000 free credits** [Start Free](https://scrapfly.io/register)