Als je onlangs hebt gezocht op "IMDb scrapen met Python", is je waarschijnlijk iets opgevallen: de meeste tutorials die je vindt, werken niet meer. Niet gewoon "een beetje verouderd" — eerder "geeft nul resultaten en een muur van NoneType-fouten" kapot.
Ik heb de afgelopen weken elke grote IMDb-scrapingtutorial getest die ik kon vinden — GeeksforGeeks, Medium, freeCodeCamp, Kaggle-notebooks, noem maar op. Van de met IMDb-scraping als label verwijst het overgrote deel naar CSS-selectors (td.titleColumn, td.ratingColumn) die sinds juni 2023 niet meer bestaan, toen IMDb de Top 250-pagina opnieuw ontwierp. Het resultaat? Forums vol ontwikkelaars die vragen: "waarom geeft mijn code niets terug?" en beheerders van populaire bibliotheken zoals : "We kunnen er niet veel aan doen, behalve elke parser fixen." Deze gids behandelt twee Python-methoden die op dit moment echt werken, hoe je omgaat met paginering en veelvoorkomende fouten, wanneer Python niet eens het juiste gereedschap is, en hoe je je scraper toekomstbestendig maakt zodat die niet op de schroothoop belandt.
Wat betekent IMDb scrapen met Python?
Webscraping is het proces waarbij je programmatisch gegevens uit webpagina's haalt — in plaats van handmatig te kopiëren en plakken, schrijf je een script dat het voor je doet. Als we het over "IMDb scrapen" hebben, bedoelen we het ophalen van gestructureerde filmdetails (titels, beoordelingen, genres, cast, speelduur, stemtellingen) van IMDb-webpagina's met Python.
De gebruikelijke Python-stack hiervoor bestaat uit drie bibliotheken: requests (om de webpagina op te halen), BeautifulSoup (om de HTML te parseren en de gegevens te vinden) en pandas (om de resultaten te ordenen en te exporteren). Sommige tutorials gebruiken ook Selenium of Playwright voor pagina's die JavaScript-rendering vereisen, maar zoals je zult zien, zijn er snellere aanpakken.
Een belangrijke kanttekening: alles in deze gids is gecontroleerd aan de hand van de huidige paginastuctuur van IMDb, medio 2025. IMDb past dingen ongeveer elke 6–12 maanden aan, dus als je dit in 2027 leest, kunnen sommige selectors verschoven zijn. (Ik leg ook uit hoe je daarmee omgaat.)
Waarom IMDb scrapen met Python? Praktische toepassingen
Voordat je ook maar één regel code schrijft: wat zou je eigenlijk doen met IMDb-data? Het antwoord hangt af van wie je bent.
De IMDb-recensiedataset is een van de meest gebruikte NLP-benchmarks ter wereld — het baanbrekende paper van Maas et al. (2011) heeft verzameld, en de dataset is ingebouwd in TensorFlow, Keras en PyTorch. Op Hugging Face krijgt de stanfordnlp/imdb-dataset 213.321 downloads per maand en is die gebruikt om meer dan 1.500 modellen te trainen. Dus als je met machine learning werkt, ben je waarschijnlijk al bekend met IMDb-data.
Maar de toepassingen gaan veel verder dan de academische wereld:
| Toepassing | Voor wie | Benodigde gegevensvelden |
|---|---|---|
| Aanbevelingsengine voor films | Data scientists, hobbyisten | Titels, genres, beoordelingen, cast |
| Contentstrategie voor streamingplatforms | Product- en contentteams | Beoordelingen, stemmen, uitgavejaar, genres |
| Sentimentanalyse / NLP-training | ML-onderzoekers, studenten | Recensies, beoordelingen |
| Concurrentieanalyse van content | Analisten in de entertainmentsector | Box office, releasedata, trends in beoordelingen |
| Onderzoek naar filmtourisme | Toerismebureaus, reisbedrijven | Filmlocaties, populariteitsmetingen |
| Academisch onderzoek | Universitaire onderzoekers | Alle gestructureerde filmdatasets |
Alleen al de markt voor filmtourisme wordt in 2025 geschat op . Netflix gaf in 2024 meer dan $17 miljard uit aan content, waarbij werd gedreven door gepersonaliseerde aanbevelingen. Het punt is: IMDb-data voedt echte beslissingen in allerlei sectoren.
Je opties om IMDb-data te krijgen (voordat je één regel code schrijft)
Dit is het onderdeel dat de meeste tutorials volledig overslaan. Ze springen direct naar pip install beautifulsoup4 zonder zich af te vragen of Python-scraping wel de juiste aanpak is voor jouw situatie.
Hier is het volledige landschap:
| Route | Het beste voor | Voordelen | Nadelen |
|---|---|---|---|
| Python + BeautifulSoup | Leren, aangepaste extractie | Volledige controle, flexibel | Kwetsbare selectors, breekt vaak |
JSON-LD / __NEXT_DATA__-extractie | Ontwikkelaars die stabiliteit willen | Verwerkt JS-content, robuuster | Vereist inzicht in JSON-structuur |
| IMDb Official Datasets | Analyse op grote schaal, academisch gebruik | Wettig, compleet, 26M+ titels, dagelijkse updates | TSV-formaat, geen recensies/afbeeldingen |
| Cinemagoer (IMDbPY)-bibliotheek | Programmatic lookups per titel | Python-achtige API, rijke velden | 88 open issues, laatste release mei 2023 |
| TMDb API | Filmmetadata + afbeeldingen | Gratis API-sleutel, JSON, goed gedocumenteerd | Andere bron (geen IMDb-beoordelingen) |
| Thunderbit (no-code) | Niet-coders, snelle exports | Scrapen in 2 klikken, AI stelt velden voor, export naar Excel/Sheets | Creditsysteem voor grote scrapes |
Een paar opmerkingen over deze opties. Cinemagoer heeft sinds mei 2023 geen PyPI-release meer gehad en de meeste parsers zijn stukgegaan na de herontwerp van IMDb in juni 2025 — ik zou het nu niet aanraden voor productiegebruik. TMDb is uitstekend, maar gebruikt een eigen beoordelingssysteem, niet dat van IMDb. En de officiële enterprise-API van IMDb kost via AWS Data Exchange , dus dat is voor de meeste mensen geen optie.
Voor lezers die helemaal geen code willen schrijven, leest de IMDb-pagina, stelt automatisch extractievelden voor (titel, beoordeling, jaar, genre) en exporteert in twee klikken naar Excel, Google Sheets, Airtable of Notion. De AI past zich aan wanneer IMDb de lay-out verandert, dus er zijn geen selectors die je hoeft bij te houden. Daar kom ik later op terug.
Nu, voor degenen die wel Python willen schrijven — hier zijn twee methoden die werken.
Methode 1: IMDb scrapen met Python via BeautifulSoup (traditionele aanpak)
Dit is de klassieke aanpak die je in de meeste tutorials terugziet. Het werkt, maar ik wil daar meteen eerlijk over zijn: het is de kwetsbaarste van de methoden die ik behandel. De CSS-classnamen van IMDb worden automatisch gegenereerd en veranderen bij herontwerpen. Dat gezegd hebbende: dit is wel de beste manier om de basisprincipes van webscraping te leren.
Stap 1: Installeer en importeer je Python-bibliotheken
Je hebt vier pakketten nodig:
1pip install requests beautifulsoup4 pandas lxml
Dit doet elk pakket:
requests— verstuurt HTTP-verzoeken om de webpagina op te halenbeautifulsoup4— parseert de HTML zodat je naar specifieke elementen kunt zoekenpandas— ordent de uitgelezen gegevens in tabellen en exporteert naar CSV/Excellxml— een snelle HTML-parser (BeautifulSoup kan die als backend gebruiken)
Je importblok:
1import requests
2from bs4 import BeautifulSoup
3import pandas as pd
Stap 2: Stuur een HTTP-verzoek naar IMDb
Hier lopen de meeste beginners meteen vast. IMDb blokkeert verzoeken zonder een correcte User-Agent-header — je krijgt dan een 403 Forbidden-fout. De standaard user-agentstring van Python Requests (python-requests/2.31.0) wordt meteen gemarkeerd.
1url = "https://www.imdb.com/chart/top/"
2headers = {
3 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
4 "Accept-Language": "en-US,en;q=0.9"
5}
6response = requests.get(url, headers=headers)
7if response.status_code != 200:
8 print(f"Pagina ophalen mislukt: {response.status_code}")
9else:
10 print("Pagina succesvol opgehaald")
De Accept-Language-header is ook belangrijk — zonder die header kan IMDb content in een andere taal teruggeven op basis van de geolocatie van je IP.
Stap 3: Parse de HTML met BeautifulSoup
Zodra je de HTML hebt, maak je een BeautifulSoup-object aan en ga je op zoek naar de juiste elementen. Open de IMDb Top 250-pagina in Chrome, klik met de rechtermuisknop op een filmtitel en kies "Inspecteren" om de onderliggende HTML-structuur te zien.
1soup = BeautifulSoup(response.text, "lxml")
Vanaf medio 2025 gebruikt de Top 250-pagina deze selectors:
- Filmcontainer:
li.ipc-metadata-list-summary-item - Titel:
h3.ipc-title__text - Jaar:
span.cli-title-metadata-item(eerste span) - Beoordeling:
span.ipc-rating-star--rating
Waarschuwing: die classnamen met ipc- ervoor worden gegenereerd door het componentsysteem van IMDb. Ze zijn stabiel gebleven sinds het herontwerp van juni 2023, maar er is geen garantie dat ze niet opnieuw veranderen.
Stap 4: Haal filmdetails op (titel, jaar, beoordeling)
Hier wijk ik af van de meeste tutorials: ik voeg try/except-foutafhandeling toe. Geen van de concurrerende gidsen die ik heb bekeken doet dat, en precies daardoor breekt hun code stilletjes wanneer een selector verandert.
1movies = []
2movie_items = soup.select("li.ipc-metadata-list-summary-item")
3for item in movie_items:
4 try:
5 title_tag = item.select_one("h3.ipc-title__text")
6 title = title_tag.text.strip() if title_tag else "N/B"
7 year_tag = item.select_one("span.cli-title-metadata-item")
8 year = year_tag.text.strip() if year_tag else "N/B"
9 rating_tag = item.select_one("span.ipc-rating-star--rating")
10 rating = rating_tag.text.strip() if rating_tag else "N/B"
11 movies.append({
12 "title": title,
13 "year": year,
14 "rating": rating
15 })
16 except Exception as e:
17 print(f"Fout bij het parsen van film: {e}")
18 continue
19print(f"{len(movies)} films uitgelezen")
Stap 5: Sla op naar CSV of Excel met Pandas
1df = pd.DataFrame(movies)
2df.to_csv("imdb_top_250.csv", index=False)
3df.to_excel("imdb_top_250.xlsx", index=False)
4print(df.head())
Voorbeelduitvoer:
1 title year rating
20 1. The Shawshank Redemption 1994 9.3
31 2. The Godfather 1972 9.2
42 3. The Dark Knight 2008 9.0
53 4. The Godfather Part II 1974 9.0
64 5. 12 Angry Men 1957 9.0
Dat werkt. Maar het leunt op CSS-selectors die op elk moment kapot kunnen gaan — en dat brengt ons bij de aanpak die ik echt aanbeveel.
Methode 2: De JSON-LD-truc — sla HTML-parsing helemaal over
Dit is de techniek die geen enkel concurrerend artikel behandelt, en de methode die ik voor elk serieus project zou gebruiken. IMDb embedt gestructureerde data als (JavaScript Object Notation for Linked Data) in <script type="application/ld+json">-tags op elke pagina. Deze data volgt de Schema.org-standaard, wordt door Google gebruikt voor rijke zoekresultaten en verandert veel minder vaak dan CSS-classnamen.
De Apify IMDb Scraper, een productietool, gebruikt de volgende prioriteitenvolgorde voor extractie: "JSON-LD > NEXT_DATA > DOM." Dat is ook de hiërarchie die ik zou aanraden.
Waarom JSON-LD betrouwbaarder is dan CSS-selectors
| Aanpak | Verwerkt JS-content? | Bestand tegen UI-wijzigingen? | Snelheid | Complexiteit |
|---|---|---|---|---|
| BeautifulSoup + CSS-selectors | ❌ Nee | ⚠️ Kwetsbaar (classnames verschuiven) | Snel | Laag |
| JSON-LD-extractie | ✅ Ja | ✅ Volgt Schema.org-standaard | Snel | Laag-matig |
__NEXT_DATA__-JSON-extractie | ✅ Ja | ✅ Redelijk stabiel | Snel | Laag-matig |
| Selenium / Playwright | ✅ Ja | ⚠️ Kwetsbaar | Traag | Matig-hoog |
| Thunderbit (no-code, 2 klikken) | ✅ Ja (AI leest de pagina) | ✅ AI past zich automatisch aan | Snel | Geen |
CSS-classnamen zoals ipc-metadata-list-summary-item worden automatisch gegenereerd door IMDb's React-componentsysteem en veranderen bij elke herontwerp. Het JSON-LD-schema vertegenwoordigt het echte datamodel, niet de presentatie-laag. Het is het verschil tussen een inhoudsopgave lezen en proberen hoofdstukken te herkennen aan de lettergrootte.

Stap voor stap: IMDb-data uit JSON-LD halen
Stap 1: Haal de pagina op
Hetzelfde als hiervoor — gebruik requests met een correcte User-Agent-header.
1import requests
2from bs4 import BeautifulSoup
3import json
4import pandas as pd
5url = "https://www.imdb.com/chart/top/"
6headers = {
7 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
8 "Accept-Language": "en-US,en;q=0.9"
9}
10response = requests.get(url, headers=headers)
11soup = BeautifulSoup(response.text, "lxml")
Stap 2: Vind de JSON-LD-script-tag
1script_tag = soup.find("script", {"type": "application/ld+json"})
2if not script_tag:
3 print("Geen JSON-LD gevonden op deze pagina")
4else:
5 data = json.loads(script_tag.string)
6 print(f"JSON-LD gevonden met type: {data.get('@type', 'onbekend')}")
Stap 3: Parse de gestructureerde data
Op de Top 250-pagina bevat JSON-LD een itemListElement-array met alle 250 films. Elk item bevat positie, naam, URL, aggregateRating, datePublished, genre, beschrijving, regisseur en acteerarrays.
1movies = []
2for item in data.get("itemListElement", []):
3 movie = item.get("item", {})
4 rating_info = movie.get("aggregateRating", {})
5 movies.append({
6 "rank": item.get("position"),
7 "title": movie.get("name"),
8 "url": movie.get("url"),
9 "rating": rating_info.get("ratingValue"),
10 "vote_count": rating_info.get("ratingCount"),
11 "date_published": movie.get("datePublished"),
12 "genre": ", ".join(movie.get("genre", [])),
13 "description": movie.get("description"),
14 })
Stap 4: Exporteren naar CSV
1df = pd.DataFrame(movies)
2df.to_csv("imdb_top_250_json_ld.csv", index=False)
3print(df.head())
Voorbeelduitvoer:
1 rank title url rating vote_count date_published genre
20 1 The Shawshank Redemption https://www.imdb.com/title/tt0111161/ 9.3 2900000 1994-10-14 Drama
31 2 The Godfather https://www.imdb.com/title/tt0068646/ 9.2 2000000 1972-03-24 Crime, Drama
42 3 The Dark Knight https://www.imdb.com/title/tt0468569/ 9.0 2800000 2008-07-18 Action, Crime, Drama
Alle 250 films. Netjes, gestructureerd, zonder CSS-selector-gedoe. En omdat deze data de Schema.org-standaard volgt (waar Google op leunt voor zoekresultaten), zal die veel minder snel veranderen dan de visuele lay-out.
Bonus: __NEXT_DATA__ voor individuele film-pagina's
Voor rijkere data van individuele titelpagina's (speelduur, volledige cast, samenvatting, posterafbeeldingen) embedt IMDb ook een __NEXT_DATA__-JSON-object. Dit is de data die React gebruikt om de pagina te hydrateren — die kun je niet verwijderen zonder de site te breken.
1# Op een individuele filmpagina zoals /title/tt0111161/
2next_data_tag = soup.find("script", {"id": "__NEXT_DATA__"})
3if next_data_tag:
4 next_data = json.loads(next_data_tag.string)
5 above_fold = next_data["props"]["pageProps"]["aboveTheFoldData"]
6 title = above_fold["titleText"]["text"]
7 year = above_fold["releaseYear"]["year"]
8 rating = above_fold["ratingsSummary"]["aggregateRating"]
9 runtime_seconds = above_fold.get("runtime", {}).get("seconds", 0)
10 genres = [g["text"] for g in above_fold["genres"]["genres"]]
11 plot = above_fold["plot"]["plotText"]["plainText"]
Gebruik JSON-LD voor chart- en lijstpagina's, __NEXT_DATA__ voor individuele titelpagina's. Dat is de production-grade aanpak.
Waarom je IMDb-scraper steeds stukgaat (en hoe je dat oplost)
Dit is verreweg het meest gemelde pijnpunt in elk IMDb-scrapingforum dat ik heb bekeken. Gebruikers schrijven: "Sommige code is kapot gegaan door UI-wijzigingen" en "Werkt niet in 2024!" — en het antwoord is meestal stilte of "probeer Selenium".
De onderliggende oorzaak is IMDb's voortdurende overstap naar een React/Next.js-frontend. Hier is de tijdlijn van grote brekende wijzigingen:
| Datum | Wat veranderde | Wat brak |
|---|---|---|
| Nov 2022 | Naam-pagina's opnieuw ontworpen | Oude naam-pagina-scrapers |
| Juni 2023 | Top 250-pagina opnieuw ontworpen | Alle td.titleColumn / td.ratingColumn-selectors |
| April 2023 | Subpagina's van titels opnieuw ontworpen | Bio-, award- en nieuwsscrapers |
| Okt 2023 | Geavanceerd zoeken opnieuw ontworpen | Zoekgebaseerde scrapers |
| Juni 2025 | /reference-pagina's opnieuw ontworpen | Cinemagoer-bibliotheek (meeste parsers) |
Dat is ongeveer één grote brekende wijziging elke 6–12 maanden. Als je scraper op CSS-classnamen leunt, ren je op een loopband.
Veelvoorkomende fouten en hoe je ze oplost
Lege resultaten / NoneType-fouten
De meest voorkomende fout. Je ziet AttributeError: 'NoneType' object has no attribute 'text'. Dat betekent dat BeautifulSoup het element dat je zoekt niet kon vinden — meestal omdat de CSS-classnaam is veranderd of omdat de content door JavaScript wordt gerenderd.
Oplossing: schakel over naar JSON-LD-extractie (Methode 2 hierboven). De data zit al in de eerste HTML-response, JavaScript is niet nodig.
403 Forbidden
IMDb gebruikt om bots te detecteren en te blokkeren. De belangrijkste trigger is een ontbrekende of duidelijk neppe User-Agent-header. Dit is gedocumenteerd in opensourceprojecten en in , waar een IMDb-medewerker het probleem erkende.
Oplossing: voeg altijd een realistische browser-User-Agent-string en een Accept-Language: en-US-header toe. Gebruik requests.Session() voor connection pooling.
Slechts 25 resultaten teruggegeven
IMDb-zoekpagina's en lijsten met "Meest populair" gebruiken lazy loading — ze tonen aanvankelijk slechts ongeveer 25 resultaten en laden meer via AJAX terwijl je scrolt.
Oplossing: gebruik paginering via URL-parameters (behandeld in de volgende sectie) of schakel over naar de Top 250-pagina, die alle 250 films in één respons laadt.
Selectors werken ineens niet meer
Oude selectors die niet meer werken: td.titleColumn, td.ratingColumn, .lister-item-header, .inline-block.ratings-imdb-rating. Als je code een van deze gebruikt, is die stuk.
Oplossing: geef de voorkeur aan data-testid-attributen (zoals h1[data-testid="hero-title-block__title"]) boven automatisch gegenereerde classnamen. Nog beter: gebruik JSON-LD.
Een besliskader: oplossingen op korte vs. lange termijn
- Snelle oplossing: voeg
try/except-blokken rond elke selector, valideer HTTP-statuscodes, log fouten in plaats van te crashen - Oplossing op middellange termijn: stap over van CSS-selectors naar JSON-LD-extractie (Methode 2)
- Oplossing op lange termijn: gebruik voor analyse op grote schaal, of een tool zoals die AI gebruikt om de paginastuctuur telkens opnieuw te lezen — geen selectors om te onderhouden, de AI past zich automatisch aan lay-outwijzigingen aan
Voorbij de grens van 25 resultaten: IMDb-paginering en grote datasets scrapen
Elke concurrerende tutorial die ik heb bekeken scrapt precies één pagina. Niemand behandelt paginering. Maar als je meer dan een enkele lijst nodig hebt, loop je snel tegen beperkingen aan.
Pagina's waarvoor geen paginering nodig is
Goed nieuws: de Top 250-pagina laadt alle 250 films in één server-gerenderde response. Zowel JSON-LD als __NEXT_DATA__ bevatten de volledige dataset. Paginering is niet nodig.
Hoe IMDb-zoekpaginering werkt
IMDb-zoekpagina's gebruiken een start=-URL-parameter, die per 50 oploopt:
1https://www.imdb.com/search/title/?groups=top_1000&start=1
2https://www.imdb.com/search/title/?groups=top_1000&start=51
3https://www.imdb.com/search/title/?groups=top_1000&start=101
Hier is een Python-loop die door de resultaten heen bladert:
1import time
2all_movies = []
3for start in range(1, 1001, 50): # Blader door de top 1000
4 url = f"https://www.imdb.com/search/title/?groups=top_1000&start={start}"
5 response = requests.get(url, headers=headers)
6 if response.status_code != 200:
7 print(f"Mislukt bij start={start}: {response.status_code}")
8 break
9 soup = BeautifulSoup(response.text, "lxml")
10 # Haal films op met je voorkeursmethode
11 # ...
12 print(f"Pagina gescrapet vanaf {start}")
13 time.sleep(3) # Wees respectvol — IMDb blokkeert na ongeveer 50 snelle verzoeken
Die time.sleep(3) is belangrijk. Uit meldingen uit de community blijkt dat IMDb IP's begint te blokkeren na ongeveer 50 snelle verzoeken. Een willekeurige vertraging tussen 2 en 5 seconden is een goede gewoonte.
Wanneer je scraping volledig moet overslaan: IMDb's officiële bulkdatasets
Voor echt grootschalige behoeften biedt IMDb 7 gratis TSV-bestanden op , dagelijks vernieuwd:
| Bestand | Inhoud | Grootte |
|---|---|---|
| title.basics.tsv.gz | Titels, typen, genres, speelduur, jaar | ~800 MB |
| title.ratings.tsv.gz | Gemiddelde beoordeling, aantal stemmen | ~25 MB |
| title.crew.tsv.gz | Regisseurs, schrijvers | ~300 MB |
| title.principals.tsv.gz | Hoofdcast/-crew | ~2 GB |
| title.akas.tsv.gz | Alternatieve titels per regio | ~1,5 GB |
| title.episode.tsv.gz | Tv-episode-informatie | ~200 MB |
| name.basics.tsv.gz | Personen: naam, geboortejaar, bekend van-titels | ~700 MB |
In Pandas laden is eenvoudig:
1ratings = pd.read_csv("title.ratings.tsv.gz", sep="\t", compression="gzip")
2basics = pd.read_csv("title.basics.tsv.gz", sep="\t", compression="gzip", low_memory=False)
3# Samenvoegen op tconst (IMDb-titel-ID)
4merged = basics.merge(ratings, on="tconst")
5top_movies = merged[merged["titleType"] == "movie"].nlargest(250, "averageRating")
Deze datasets omvatten meer dan 26 miljoen titels. Geen paginering, geen selectors, geen 403-fouten. De licentie is alleen voor persoonlijk en niet-commercieel gebruik — je mag de data niet opnieuw publiceren of doorverkopen.
De no-code snelweg: Thunderbit regelt paginering voor je
Voor lezers die gepagineerde IMDb-data nodig hebben maar geen pagineringslogica willen schrijven, ondersteunt zowel klikgebaseerde paginering als oneindig scrollen native. Jij zegt wat er gescrapet moet worden, Thunderbit doet de rest — inclusief scrollen door lazy-loaded content.
IMDb scrapen met Python: complete werkende code (klaar om te kopiëren en plakken)
Hier zijn twee zelfstandige scripts die je nu meteen kunt draaien.
Script A: BeautifulSoup-methode (CSS-selectors)
1import requests
2from bs4 import BeautifulSoup
3import pandas as pd
4url = "https://www.imdb.com/chart/top/"
5headers = {
6 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
7 "Accept-Language": "en-US,en;q=0.9"
8}
9response = requests.get(url, headers=headers)
10if response.status_code != 200:
11 print(f"Fout: {response.status_code}")
12 exit()
13soup = BeautifulSoup(response.text, "lxml")
14movie_items = soup.select("li.ipc-metadata-list-summary-item")
15movies = []
16for item in movie_items:
17 try:
18 title = item.select_one("h3.ipc-title__text")
19 year = item.select_one("span.cli-title-metadata-item")
20 rating = item.select_one("span.ipc-rating-star--rating")
21 movies.append({
22 "title": title.text.strip() if title else "N/B",
23 "year": year.text.strip() if year else "N/B",
24 "rating": rating.text.strip() if rating else "N/B",
25 })
26 except Exception as e:
27 print(f"Film overgeslagen door fout: {e}")
28df = pd.DataFrame(movies)
29df.to_csv("imdb_top250_bs4.csv", index=False)
30print(f"{len(df)} films opgeslagen")
31print(df.head())
Script B: JSON-LD-methode (aanbevolen)
1import requests
2from bs4 import BeautifulSoup
3import json
4import pandas as pd
5url = "https://www.imdb.com/chart/top/"
6headers = {
7 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
8 "Accept-Language": "en-US,en;q=0.9"
9}
10response = requests.get(url, headers=headers)
11if response.status_code != 200:
12 print(f"Fout: {response.status_code}")
13 exit()
14soup = BeautifulSoup(response.text, "lxml")
15script_tag = soup.find("script", {"type": "application/ld+json"})
16if not script_tag:
17 print("Geen JSON-LD-data gevonden")
18 exit()
19data = json.loads(script_tag.string)
20movies = []
21for item in data.get("itemListElement", []):
22 movie = item.get("item", {})
23 rating_info = movie.get("aggregateRating", {})
24 directors = movie.get("director", [])
25 director_names = ", ".join(
26 d.get("name", "") for d in (directors if isinstance(directors, list) else [directors])
27 )
28 movies.append({
29 "rank": item.get("position"),
30 "title": movie.get("name"),
31 "url": movie.get("url"),
32 "rating": rating_info.get("ratingValue"),
33 "votes": rating_info.get("ratingCount"),
34 "year": movie.get("datePublished", "")[:4],
35 "genre": ", ".join(movie.get("genre", [])),
36 "director": director_names,
37 "description": movie.get("description"),
38 })
39df = pd.DataFrame(movies)
40df.to_csv("imdb_top250_jsonld.csv", index=False)
41print(f"{len(df)} films opgeslagen")
42print(df.head())
Beide scripts bevatten foutafhandeling en leveren een nette CSV-uitvoer op. Script B geeft je rijkere data — regisseur, beschrijving, URL — en is beter bestand tegen lay-outwijzigingen.
Hoe je IMDb kunt scrapen zonder code te schrijven (met Thunderbit)
Niet iedereen hoeft of wil Python schrijven. Misschien ben je een operations-analist die alleen de best beoordeelde films van deze week in een spreadsheet nodig heeft. Misschien ben je een contentstrateeg die genretrends over de jaren wil vergelijken. In die gevallen is het schrijven van een scraper overkill.
Zo haal je dezelfde data op met :
Voordat je begint:
- Moeilijkheidsgraad: Beginner
- Benodigde tijd: ~2 minuten
- Wat je nodig hebt: Chrome-browser, (gratis laag werkt)
Stap 1: Ga naar de IMDb-pagina die je wilt scrapen. Open de IMDb Top 250 (of een andere IMDb-lijst-/zoekpagina) in Chrome.
Stap 2: Klik op "AI Suggest Fields" in de Thunderbit-zijbalk. De AI scant de pagina en stelt kolommen voor — meestal Titel, Jaar, Beoordeling, Genre en nog een paar andere, afhankelijk van de pagina. Je ziet een voorbeeldtabel met de voorgestelde velden.
Stap 3: Pas velden aan indien nodig. Verwijder kolommen die je niet nodig hebt, of voeg eigen kolommen toe door op "+ Kolom toevoegen" te klikken en in gewoon Nederlands te beschrijven wat je wilt (bijv. "Naam van de regisseur" of "Aantal stemmen").
Stap 4: Klik op "Scrapen". Thunderbit haalt de gegevens op. Voor pagina's met oneindig scrollen of paginering regelt het automatisch het scrollen.
Stap 5: Exporteer. Klik op de exportknop en kies je formaat — Excel, Google Sheets, CSV, Airtable of Notion. De gegevens staan binnen enkele seconden op hun bestemming.
Het belangrijkste voordeel hier is niet alleen gemak — het is dat Thunderbit's AI de paginastuctuur elke keer opnieuw leest. Wanneer IMDb zijn lay-out verandert (en dat zal gebeuren), past de AI zich aan. Geen selectors om bij te werken, geen code om te repareren. Voor iedereen die ooit om 2 uur 's nachts vlak voor een deadline is vastgelopen op een kapotte scraper, is dat heel wat waard.
Thunderbit ondersteunt ook subpage scraping — je kunt doorklikken naar de detailpagina van elke film en je tabel verrijken met cast, regisseur, speelduur en andere velden die niet zichtbaar zijn op de lijstpagina. Wil je het in actie zien, bekijk dan het .
Is het legaal om IMDb te scrapen? Wat je moet weten
Gebruikers stellen dit expliciet in forums: "Is iets als dit legaal?… IMDb wil niet dat mensen hun website scrapen." Het is een terechte vraag, en geen enkel concurrerend artikel behandelt die.
IMDb's robots.txt: De Top 250-chart (/chart/top/), individuele titelpagina's (/title/ttXXXXXXX/) en naamspagina's (/name/nmXXXXXXX/) worden NIET geblokkeerd door robots.txt. Geblokkeerde paden zijn onder meer /find, /_json/*, /search/name-text, /user/ur*/ratings en verschillende AJAX-endpoints. Er is geen Crawl-delay-directive opgegeven.
IMDb's Gebruiksvoorwaarden: De relevante clausule luidt: "Je mag geen datamining, robots, screen scraping of vergelijkbare tools voor gegevensverzameling en extractie op deze site gebruiken, behalve met onze uitdrukkelijke schriftelijke toestemming." Een aanvullende clausule verbiedt wederverkoop of commercieel gebruik van gescrapete data.
Wat dit in de praktijk betekent: Recente rechtszaken uit 2024 (Meta v. Bright Data, X Corp v. Bright Data) oordeelden dat algemene voorwaarden mogelijk niet bindend zijn voor gebruikers die er nooit mee hebben ingestemd — als je publiek beschikbare gegevens scrapt zonder in te loggen, is de afdwingbaarheid van de ToS discutabel. Maar dit rechtsgebied is in beweging.
Veilige alternatieven: IMDb's zijn expliciet toegestaan voor persoonlijk en niet-commercieel gebruik. De API van TMDb is ruimhartig met een gratis API-sleutel. Beide zijn solide opties als je duidelijk binnen de regels wilt blijven.
Praktisch advies: Als je toch scrapt, gebruik dan een respectvolle crawl-snelheid (time.sleep(3) tussen verzoeken), stel correcte headers in en raak geen paden aan die door robots.txt worden geblokkeerd. Voor commerciële projecten: raadpleeg een juridisch professional of gebruik de officiële datasets/API.
We hebben de uitgebreid behandeld op de Thunderbit-blog.
Conclusie: kies de juiste manier om IMDb met Python te scrapen
De korte versie:
- BeautifulSoup + CSS-selectors: Goed om de basis te leren. Verwacht dat het elke 6–12 maanden stukgaat. Voeg altijd foutafhandeling toe.
- JSON-LD-extractie: De aanpak die ik zou aanraden voor elk lopend Python-project. Volgt de Schema.org-standaard, verandert veel minder vaak dan CSS-klassen en geeft je schone, gestructureerde data zonder JavaScript-rendering.
__NEXT_DATA__-JSON: Gebruik dit aanvullend voor rijkere data op individuele titelpagina's (speelduur, volledige cast, plot, posterafbeeldingen).- IMDb Official Datasets: De beste keuze voor analyse op grote schaal. 26M+ titels, dagelijks bijgewerkt, geen scraping nodig. Alleen voor persoonlijk/niet-commercieel gebruik.
- : De beste keuze voor niet-coders of iedereen die snel data wil zonder code te onderhouden. AI past zich aan lay-outwijzigingen aan, regelt paginering en exporteert naar Excel/Sheets/Airtable/Notion.
Sla deze gids op — ik werk hem bij zodra IMDb's structuur weer verandert. En als je de code helemaal wilt overslaan, en zie hoe snel je van een IMDb-pagina naar een nette spreadsheet gaat. Als je ook met andere sites werkt, behandelt onze gids over de bredere workflow.
FAQ's
Is het legaal om IMDb te scrapen?
IMDb's Gebruiksvoorwaarden verbieden scrapen zonder toestemming, maar de afdwingbaarheid van die voorwaarden op publiek toegankelijke gegevens is juridisch discutabel na recente rechtszaken in 2024. De veiligste opties zijn IMDb's (persoonlijk/niet-commercieel gebruik) of de TMDb API (gratis sleutel). Als je toch scrapt, respecteer robots.txt, gebruik redelijke vertragingen tussen verzoeken en vermijd geblokkeerde paden. Raadpleeg voor commercieel gebruik een juridisch professional.
Waarom geeft mijn IMDb-scraper lege resultaten terug?
Bijna altijd komt dat door verouderde CSS-selectors — classnamen zoals td.titleColumn en td.ratingColumn bestaan sinds juni 2023 niet meer. De oplossing is overstappen op JSON-LD-extractie (parse de <script type="application/ld+json">-tag) of je selectors bijwerken naar de huidige ipc--gepreficeerde classes. Controleer ook of je een correcte User-Agent-header meestuurt, want een ontbrekende header kan een 403-fout veroorzaken die eruitziet als lege resultaten.
Hoe scrape ik meer dan 25 resultaten van IMDb?
De Top 250-pagina laadt alle 250 films in één response — geen paginering nodig. Gebruik voor zoekresultaten de start=-URL-parameter (in stappen van 50) om door de resultaten te bladeren. Bijvoorbeeld: start=1, start=51, start=101. Voeg time.sleep(3) toe tussen verzoeken om blokkering te voorkomen. Als alternatief bevatten IMDb's officiële datasets op meer dan 26 miljoen titels zonder dat paginering nodig is.
Wat is __NEXT_DATA__ en waarom zou ik het gebruiken om IMDb te scrapen?
__NEXT_DATA__ is een JSON-object dat op IMDb's React/Next.js-pagina's in een <script id="__NEXT_DATA__">-tag is ingesloten. Het bevat de volledige gestructureerde data die React gebruikt om de pagina te renderen — titels, beoordelingen, cast, genres, speelduur en meer. Omdat het het onderliggende datamodel weergeeft in plaats van de visuele lay-out, is het beter bestand tegen herontwerpen van de UI dan CSS-selectors. Gebruik het naast JSON-LD voor de meest robuuste extractie-aanpak.
Kan ik IMDb scrapen zonder te programmeren?
Ja. Twee hoofdopties: (1) Download IMDb's — 7 TSV-bestanden die meer dan 26 miljoen titels dekken, dagelijks bijgewerkt, gratis voor niet-commercieel gebruik. (2) Gebruik , die de IMDb-pagina leest, automatisch extractievelden voorstelt en in twee klikken exporteert naar Excel, Google Sheets of CSV — geen code, geen selectors om te onderhouden.
Meer lezen