En introduksjon til nettskraping med Cheerio

Nettskraping er en teknikk som gjør det mulig å hente data fra en bestemt nettside. Nettsteder bruker HTML for å beskrive innholdet. Hvis HTML-en er ren og semantisk, er det lett å bruke den til å finne nyttige data.

Du vil vanligvis bruke en nettskraper for å innhente og overvåke data og spore fremtidige endringer i dem.

jQuery-konsepter som er verdt å vite før du bruker Cheerio

jQuery er en av de mest populære JavaScript-pakkene som finnes. Det gjør det enklere å jobbe med Document Object Model (DOM), håndtere hendelser, animasjoner og mer. Cheerio er en pakke for nettskraping som bygger på toppen av jQuery – som deler samme syntaks og API, samtidig som det gjør det enklere å analysere HTML- eller XML-dokumenter.

Før du lærer hvordan du bruker Cheerio, er det viktig å vite hvordan du velger HTML-elementer med jQuery. Heldigvis støtter jQuery de fleste CSS3-velgere som gjør det lettere å hente elementer fra DOM. Ta en titt på følgende kode:

 $("#container");

I kodeblokken ovenfor velger jQuery elementene med ID-en til «container». En lignende implementering med vanlig gammel JavaScript vil se omtrent slik ut:

 document.querySelectorAll("#container");

Ved å sammenligne de to siste kodeblokkene kan du se at den tidligere kodeblokken er mye lettere å lese enn sistnevnte. Det er det fine med jQuery.

jQuery har også nyttige metoder som text(), html() og mer som gjør det mulig å manipulere HTML-elementer. Det er flere metoder du kan bruke for å krysse DOM, som parent(), søsken(), prev() og next().

each()-metoden i jQuery er veldig populær i mange Cheerio-prosjekter. Den lar deg iterere over objekter og matriser. Syntaksen for each()-metoden ser slik ut:

 $(<element>).each(<array or object>, callback)

I kodeblokken ovenfor kjører tilbakeringing for hver iterasjon av matrisen eller objektargumentet.

  Hvordan lage en virtuell KVM-maskin i Ubuntu

Laster HTML med Cheerio

For å begynne å analysere HTML- eller XML-data med Cheerio, kan du bruke cheerio.load()-metoden. Ta en titt på dette eksemplet:

 const $ = cheerio.load('<html><body><h1>Hello, world!</h1></body></html>');
console.log($('h1').text())

Denne kodeblokken bruker jQuery text()-metoden henter tekstinnholdet til h1-elementet. Den fullstendige syntaksen for load()-metoden ser slik ut:

 load(content, options, mode)

Innholdsparameteren refererer til de faktiske HTML- eller XML-dataene du sender load()-metoden. options er et valgfritt objekt som kan endre oppførselen til metoden. Som standard introduserer load()-metoden html-, head- og body-elementer hvis de mangler. Hvis du vil stoppe denne oppførselen, må du sørge for at du setter modus til usann.

Skraper hackernyheter med Cheerio

Koden som brukes i dette prosjektet er tilgjengelig i en GitHub-depot og er gratis for deg å bruke under MIT-lisensen.

Det er på tide å kombinere alt du har lært så langt og lage en enkel nettskraper. Hacker News er et populært nettsted for gründere og innovatører. Det er også et perfekt nettsted å bruke ferdighetene dine til å skrape nett på fordi det laster raskt, har et veldig enkelt grensesnitt og ikke viser noen annonser.

Sørg for at du har Node.js og Node Package Manager kjørende på maskinen din. Opprett en tom mappe, deretter en package.json-fil, og legg til følgende JSON i filen:

 {
  "name": "web-scraper",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon index.js"
  },
  "author": "",
  "license": "MIT",
  "dependencies": {
    "cheerio": "^1.0.0-rc.12",
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^3.0.1"
  }
}

Etter å ha gjort det, åpne terminalen og kjør:

 npm i

Dette bør installere de nødvendige avhengighetene du trenger for å bygge skraperen. Disse pakkene inkluderer Cheerio for å analysere HTML, ExpressJS for å lage serveren, og – som en utviklingsavhengighet – Nodemon, et verktøy som lytter etter endringer i prosjektet og automatisk starter serveren på nytt.

  Topp 14 produktbeskrivelse Generatorer for å øke salget ditt

Sette opp ting og lage de nødvendige funksjonene

Lag en index.js-fil, og lag en konstant variabel kalt «PORT» i den filen. Sett PORT til 5500 (eller hvilket nummer du velger), og importer deretter henholdsvis Cheerio- og Express-pakkene.

 const PORT = 5500;
const cheerio = require("cheerio");
const express = require("express");
const app = express();

Definer deretter tre variabler: url, html og finishedPage. Sett url til Hacker News URL.

 const url="https://news.ycombinator.com";
let html;
let finishedPage;

Lag nå en funksjon kalt getHeader() som returnerer noe HTML som nettleseren skal gjengi.

 function getHeader(){
    return `
        <div style="display:flex; flex-direction:column; align-items:center;">
        <h1 style="text-transform:capitalize">Scraper News</h1>
        <div style="display:flex; gap:10px; align-items:center;">
        <a href="https://www.makeuseof.com/" id="news" onClick='showLoading()'>Home</a>
        <a href="https://wilku.top/best" id="best" onClick='showLoading()'>Best</a>
        <a href="https://wilku.top/newest" id="newest" onClick='showLoading()'>Newest</a>
        <a href="https://wilku.top/ask" id="ask" onClick='showLoading()'>Ask</a>
        <a href="https://wilku.top/jobs" id="jobs" onClick='showLoading()'>Jobs</a>
        </div>
        <p class="loading" style="display:none;">Loading...</p>
        </div>
`}

Opprett en annen funksjon getScript() som returnerer noe JavaScript for nettleseren å kjøre. Pass på at du sender inn variabeltypen som argument når du kaller den.

 function getScript(type){
    return `
    <script>
    document.title = "${type.substring(1)}"

    window.addEventListener("DOMContentLoaded", (e) => {
      let navLinks = [...document.querySelectorAll("a")];
      let current = document.querySelector("#${type.substring(1)}");
      document.body.style = "margin:0 auto; max-width:600px;";
      navLinks.forEach(x => x.style = "color:black; text-decoration:none;");
      current.style.textDecoration = "underline";
      current.style.color = "black";
      current.style.padding = "3px";
      current.style.pointerEvents = "none";
    })

    function showLoading(e){
      document.querySelector(".loading").style.display = "block";
      document.querySelector(".loading").style.textAlign = "center";
    }
    </script>`
}

Til slutt, lag en asynkron funksjon kalt fetchAndRenderPage(). Denne funksjonen gjør akkurat det du tror – den skraper en side i Hacker News, analyserer og formaterer den med Cheerio, og sender deretter litt HTML tilbake til klienten for gjengivelse.

 async function fetchAndRenderPage(type, res) {
    const response = await fetch(`${url}${type}`)
    html = await response.text();
}

På Hacker News er det forskjellige typer innlegg tilgjengelig. Det er «nyhetene», som er tingene på forsiden, innlegg som søker svar fra andre Hacker News-medlemmer har etiketten «spør». Trendende innlegg har etiketten «best», de siste innleggene har etiketten «nyeste» og innlegg om ledige stillinger har etiketten «jobber».

  Slik fikser du at Epic Games Launcher ikke fungerer

fetchAndRenderPage() henter listen over innlegg fra Hacker News-siden basert på typen du sender inn som argument. Hvis henteoperasjonen er vellykket, binder funksjonen html-variabelen til svarteksten.

Deretter legger du til følgende linjer til funksjonen:

 res.set('Content-Type', 'text/html');
res.write(getHeader());

const $ = cheerio.load(html);
const articles = [];
let i = 1;

I kodeblokken ovenfor setter set()-metoden HTTP-header-feltet. Write()-metoden er ansvarlig for å sende en del av svarteksten. load()-funksjonen tar inn html som et argument.

Deretter legger du til følgende linjer for å velge de respektive barna til alle elementene med klassen «tittellinje».

 $('.titleline').children('a').each(function(){
    let title = $(this).text();
    articles.push(`<h4>${i}. ${title}</h4>`);
    i++;
})

I denne kodeblokken henter hver iterasjon tekstinnholdet til HTML-målelementet og lagrer det i tittelvariabelen.

Deretter skyver du svaret fra getScript()-funksjonen inn i artikkelmatrisen. Deretter oppretter du en variabel, finishedPage, som vil inneholde den ferdige HTML-koden for å sende til nettleseren. Til slutt, bruk write()-metoden for å sende finishedPage som en del og avslutt svarprosessen med end()-metoden.

 articles.push(getScript(type))
finishedPage = articles.reduce((c, n) => c + n);
res.write(finishedPage);
res.end();

Definere rutene for å håndtere GET-forespørsler

Rett under fetchAndRenderPage-funksjonen, bruk express get()-metoden for å definere de respektive rutene for forskjellige typer innlegg. Bruk deretter lyttemetoden for å lytte etter tilkoblinger til den angitte porten på ditt lokale nettverk.

 app.get("https://www.makeuseof.com/", (req, res) => {
    fetchAndRenderPage('/news', res);
})

app.get("https://wilku.top/best", (req, res) => {
    fetchAndRenderPage("https://wilku.top/best", res);
})

app.get("https://wilku.top/newest", (req, res) => {
    fetchAndRenderPage("https://wilku.top/newest", res);
})

app.get("https://wilku.top/ask", (req, res) => {
    fetchAndRenderPage("https://wilku.top/ask", res);
})

app.get("https://wilku.top/jobs", (req, res) => {
    fetchAndRenderPage("https://wilku.top/jobs", res);
})

app.listen(PORT)

I kodeblokken ovenfor har hver get-metode en tilbakeringingsfunksjon som kaller fetchAndRenderPage-funksjonen som passerer i respektive typer og res-objektene.

Når du åpner terminalen og kjører npm, start. Serveren skal starte opp, så kan du besøke localhost:5500 i nettleseren din for å se resultatene.

Gratulerer, du klarte akkurat å skrape Hacker News og hente posttitlene uten behov for en ekstern API.

Ta ting videre med nettskraping

Med dataene du skraper fra Hacker News, kan du lage ulike visualiseringer som diagrammer, grafer og ordskyer for å presentere innsikt og trender i et mer fordøyelig format.

Du kan også skrape brukerprofiler for å analysere omdømmet til brukere på plattformen basert på faktorer som mottatte oppstemmer, kommentarer og mer.