Je hebt de perfecte dataset gevonden op een website. Nu heb je die in Pandas nodig.
De traditionele aanpak:
import pandas as pd
# Hopen dat de websitestructuur simpel is
tables = pd.read_html('https://example.com/data')
# Raden welke tabel je wilt
df = tables[0] # Misschien? Laten we eens kijken...
# De problemen ontdekken
print(df.dtypes)
# Alles is 'object' (string)
# Getallen hebben punten
# Datums zijn niet parseerbaar
# Kolomnamen hebben spaties
# 30 minuten opschonen...
Laat me je een snellere manier laten zien.
Het Probleem met pd.read_html()
Pandas' read_html() is handig maar beperkt:
Geen tabelselectie — Het pakt alle tabellen. Je raadt welke index je nodig hebt.
Geen opschoning — Getallen zoals "1.234.567" blijven strings.
CORS-problemen — Veel sites blokkeren programmatische toegang.
JavaScript-rendering — Dynamische tabellen bestaan niet in de ruwe HTML.
Authenticatie — Kan geen ingelogde content bereiken.
Voor snelle scripts werkt het. Voor serieuze analyse heb je iets beters nodig.
De 30-Seconden Workflow
Dit is wat ik werkelijk doe:
Stap 1: Exporteren vanuit de Browser (5 seconden)
Met HTML Table Exporter:
- Klik op de tabel die ik wil
- Klik op het extensie-icoon
- Selecteer het "Voor Pandas"-profiel
- Exporteer als CSV vanuit de gemarkeerde tabel in de extensie
De extensie ziet precies wat jouw browser ziet—JavaScript-gerenderde content, ingelogde pagina's, alles.
Stap 2: Laden in Pandas (5 seconden)
import pandas as pd
df = pd.read_csv('export.csv')
print(df.dtypes)
Dat is het. De data is al schoon.
Wat "Schoon" Echt Betekent
Als ik exporteer met het "Voor Pandas"-profiel, handelt de extensie het volgende af:
Getalnormalisatie
Voorheen: "1.234.567,89" (Europees formaat)
Erna: 1234567.89 (float)
Voorheen: "€1.234,56"
Erna: 1234.56
De CSV bevat genormaliseerde getallen die Pandas correct parset:
# Zonder opschoning:
df['omzet'].sum() # TypeError: can only concatenate str
# Met opschoning:
df['omzet'].sum() # 4892341.50 ✓
Boolean-Conversie
Voorheen: "Ja", "Nee", "J", "N", "True", "False"
Erna: true, false
# Filteren werkt direct
actieve_gebruikers = df[df['is_actief'] == True]
Null-Afhandeling
Voorheen: "-", "N.v.t.", "n.v.t.", "", "null", "—"
Erna: (leeg, geparsed als NaN)
# Null-detectie werkt
df['optioneel_veld'].isna().sum() # Correcte telling
Snake Case Headers
Voorheen: "Omzet (€M)", "Aantal Gebruikers", "Groeipercentage %"
Erna: omzet_m, aantal_gebruikers, groeipercentage
# Schone kolomtoegang
df['omzet_m'] # In plaats van df['Omzet (€M)']
Reëel Voorbeeld: FBRef Voetbalstatistieken
Stel dat ik Premier League spelerstatistieken wil van FBRef.
De Oude Manier
import pandas as pd
import requests
from bs4 import BeautifulSoup
url = 'https://fbref.com/en/comps/9/stats/Premier-League-Stats'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# De juiste tabel vinden (er zijn er veel)
table = soup.find('table', {'id': 'stats_standard'})
# Handmatig parsen omdat de headers complex zijn
# FBRef gebruikt gegroepeerde headers: "Playing Time" overspant meerdere kolommen
# Dit breekt pd.read_html()
# 45 minuten later...
De Nieuwe Manier
- Open FBRef in de browser
- Klik extensie → selecteer tabel → exporteer met "Voor Pandas"-profiel
- Laden:
df = pd.read_csv('fbref_stats.csv')
print(df.columns.tolist())
# ['player', 'nation', 'squad', 'playing_time_mp',
# 'playing_time_starts', 'performance_gls', ...]
De gegroepeerde headers ("Playing Time", "Performance") worden automatisch samengevoegd met subheaders.
De Code Die Ik Niet Meer Schrijf
Hier is opschooncode die ik vroeger voor elke webscrape schreef:
def clean_web_data(df):
"""De functie die ik niet meer nodig heb."""
# Getalkolommen repareren
for col in df.select_dtypes(include='object'):
# Probeer te converteren naar numeriek
try:
# Valutasymbolen verwijderen
cleaned = df[col].str.replace(r'[$€£¥]', '', regex=True)
# Duizendtalscheidingstekens verwijderen
cleaned = cleaned.str.replace(',', '')
# Converteren
df[col] = pd.to_numeric(cleaned, errors='ignore')
except:
pass
# Boolean-kolommen repareren
bool_map = {
'ja': True, 'nee': False,
'true': True, 'false': False,
'j': True, 'n': False,
'1': True, '0': False,
}
for col in df.columns:
if df[col].str.lower().isin(bool_map.keys()).all():
df[col] = df[col].str.lower().map(bool_map)
# Null-waarden repareren
null_values = ['', '-', 'N.v.t.', 'n.v.t.', 'null', 'NULL', '—', '–']
df = df.replace(null_values, np.nan)
# Kolomnamen repareren
df.columns = (df.columns
.str.lower()
.str.replace(r'[^a-z0-9]+', '_', regex=True)
.str.strip('_'))
return df
Deze functie draaide op elke dataset. Nu handelt de export dat af.
Wanneer Wat Gebruiken
| Scenario | Beste Aanpak |
|---|---|
| Eenmalige analyse | Browserexport → CSV → Pandas |
| Herhaald scrapen | Python-script met requests
|
| JavaScript-zware sites | Browserexport (ziet gerenderde content) |
| Ingelogde data | Browserexport (gebruikt je sessie) |
| API beschikbaar | Gebruik de API rechtstreeks |
| Eenvoudige statische tabel |
pd.read_html() is prima |
Pro Tip: JSON voor Complexe Data
Voor geneste of getypeerde data, exporteer als JSON:
import pandas as pd
import json
with open('export.json') as f:
data = json.load(f)
df = pd.DataFrame(data)
De JSON-export behoudt types:
- Getallen als getallen (niet strings)
- Booleans als booleans
- Nulls als null
print(df.dtypes)
# player object
# goals int64 # Al numeriek!
# is_starter bool # Al boolean!
# injury_date object # Kan geparsed worden als datetime
Zie voor meer details over JSON-workflows Webtabellen Exporteren naar JSON voor Python & Pandas.
De Workflow Samengevat
Oude workflow (30+ minuten):
- Scraping-script schrijven
- CORS/auth-problemen afhandelen
- Complexe HTML parsen
- Getallen opschonen
- Booleans opschonen
- Nulls opschonen
- Kolomnamen repareren
- Edge cases debuggen
- Eindelijk: analyseren
Nieuwe workflow (30 seconden):
- Klik extensie
- Exporteer met opschoonprofiel
pd.read_csv()- Analyseren
Probeer Het
- Installeer HTML Table Exporter
- Zoek een tabel die je wilt analyseren
- Exporteer met opschoonpresets
- Laad in Pandas
De gratis versie handelt basisexporten af. PRO voegt opschoonpresets en profielen toe voor Pandas-geoptimaliseerde output.
Meer informatie op gauchogrid.com/nl/html-table-exporter of probeer het in de Chrome Web Store.
Wat is jouw huidige workflow voor het laden van webdata in Pandas? Ik ben benieuwd hoeveel tijd je besteedt aan de opschoonstap. Laat een reactie achter.
Top comments (0)