Hvordan Utføre Profesjonell Webskraping med Python og Selenium

Profilbilde av Felix Sandström, artikkelens forfatter

Felix Sandström

Webskraping er en effektiv metode for å hente data fra nettsider som ikke tilbyr API-er eller nedlastbar data. I dette innlegget vil jeg demonstrere et mer avansert eksempel ved hjelp av Python og Selenium, hvor vi går gjennom kontinenter og land på en nettside for å samle inn energidata.

Vi skal:

  • Hente en liste over alle kontinenter fra nettsiden.
  • Navigere til hver kontinentside og hente en liste over land.
  • Besøke hver lands side og samle spesifikke data som år, utslipp, og elektrisitetsforbruk.
  • Strukturere dataene i en CSV-fil for videre analyse.

Hvordan Nettsiden Ser Ut

Før vi begynner med koden, må vi forstå hvordan nettsiden ser ut. Dette gir oss en bedre forståelse av elementene vi skal hente:

Oversikt over kontinenter på nettsiden

Hovedsiden som viser alle kontinenter med lenker til landsider.

Eksempel på en landside

En typisk landside hvor vi henter data som år, globale utslipp og grafer.

Steg 1: Initialisere Nettleseren

Vi starter med å initialisere en nettleser ved hjelp av Selenium. Dette gir oss muligheten til å samhandle med nettsider som bruker dynamisk JavaScript-innhold. Oppsettet inkluderer optimaliseringer for ytelse og stabilitet:


    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options

    def initialize_browser():
        options = Options()
        options.add_argument("--no-sandbox")
        options.add_argument("--disable-dev-shm-usage")
        options.add_argument("--disable-gpu")
        options.add_argument("--window-size=1920,1080")
        driver = webdriver.Chrome(options=options)
        return driver
    

Steg 2: Hente Kontinenter

Når nettleseren er satt opp, navigerer vi til hovedsiden for å hente en liste over kontinenter. Dette gjøres ved å identifisere lenker ved hjelp av XPath og andre selektorer som vi finner gjennom inspeksjonsverktøyet:


    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC

    def get_continent_links(driver, base_url):
        driver.get(f"{base_url}/countries")
        continent_links = WebDriverWait(driver, 10).until(
            EC.presence_of_all_elements_located((By.XPATH, "//a[contains(@class, 'm-regions-listing__link')]"))
        )
        return [
            (link.get_attribute("href"), link.find_element(By.TAG_NAME, "h3").text)
            for link in continent_links
        ]
    

Steg 3: Hente Land fra Kontinent

Deretter navigerer vi til hver kontinentside og henter en liste over land. Her bruker vi lignende metoder som i forrige steg:


    def get_country_links(driver, continent_url):
        driver.get(continent_url)
        country_links = WebDriverWait(driver, 10).until(
            EC.presence_of_all_elements_located((By.XPATH, "//a[contains(@class, 'm-country-listing__link')]"))
        )
        return [link.get_attribute("href") for link in country_links]
    

Steg 4: Skrape Data fra Land

Vi besøker hver lands side for å hente spesifikke data. Sidene inneholder diagrammer som viser nøkkelinformasjon som fornybar energi, «Total energy supply», og «Electricity». Disse dataene er spredt over ulike tabulater, og for å samle fullstendig informasjon må vi navigere mellom tabulatene og hente data fra hver.

I noen tilfeller kan prosentandelen for fornybare energikilder være skjult i diagrammet. Dette skjer ofte når siden bruker JavaScript for å skjule etiketter som overlapper hverandre. For å hente denne informasjonen må vi implementere JavaScript-interaksjoner for å avdekke de skjulte elementene.

Grafelementer på landsiden

Skjermbildet viser hvilke data vi ønsker å hente ut, inkludert årstall, sammenstilt energidata, energimiks, elektrisitetsmiks og CO2-utslipp.


    def scrape_country_data(driver, country_url):
        driver.get(country_url)
        data = {"Country": country_url.split("/")[-1].replace("-", " ").title()}

        try:
            year = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.XPATH, "//p[contains(text(), 'Total energy supply')]"))
            ).text
            data["Year"] = re.search(r"(\d{4})", year).group(1)

            emissions = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.XPATH, "//span[contains(@class, 'f-title-2') and contains(text(), '%')]"))
            ).text
            data["Global Emissions"] = re.match(r"(\d+\.?\d*)%", emissions).group(1) + "%"

            energy_data = scrape_hidden_chart_data(driver)
            if energy_data:
                data.update({f"Energy Supplied {k}": v for k, v in energy_data.items()})

        except Exception as e:
            print(f"Error scraping {country_url}: {e}")

        return data
    

Resultat

Med dette scriptet kan vi hente et strukturert datasett fra nettsiden. Her er et eksempel på datasettet:

Eksempel på skrapte energidata

Eksempel på skrapte energidata fra nettsiden i CSV-format.

Oppsummering

Dette eksemplet demonstrerer hvordan man kan navigere og hente data fra komplekse nettsider ved hjelp av Selenium. Vi startet med å hente kontinenter, navigerte gjennom landsider, og samlet data i en strukturert form. Dette gir et robust utgangspunkt for videre analyser innen energi og klima.

I fremtidige artikler vil vi dekke mer avanserte teknikker, inkludert bedre feilhåndtering og bruk av API-er der det er mulig. Utforsk hele prosjektet på mitt GitHub-repository og prøv det selv!

Relaterte Artikler

Kommentarer (0)

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *

KONTAKT

Har du spørsmål, ideer eller ønsker å vite mer, er du hjertelig velkommen til å fylle ut kontaktskjemaet, sende en e-post eller ringe.

info@felixwebutvikling.no

+47 40496181

Slettestien 3

4050 Sola

Org.nr: 934 781 864

KONTAKTSKJEMA