O introducere în web scraping cu Cheerio

Web scraping este o tehnică care face posibilă obținerea de date de pe un anumit site web. Site-urile web folosesc HTML pentru a-și descrie conținutul. Dacă HTML-ul este curat și semantic, este ușor să îl utilizați pentru a localiza date utile.

De obicei, veți folosi un web scraper pentru a obține și monitoriza date și pentru a urmări modificările viitoare ale acestora.

Concepte jQuery care merită cunoscute înainte de a utiliza Cheerio

jQuery este unul dintre cele mai populare pachete JavaScript existente. Facilitează lucrul cu Document Object Model (DOM), gestionarea evenimentelor, animația și multe altele. Cheerio este un pachet pentru web scraping care se bazează pe jQuery – partajând aceeași sintaxă și API, facilitând în același timp analizarea documentelor HTML sau XML.

Înainte de a învăța cum să folosești Cheerio, este important să știi cum să selectezi elemente HTML cu jQuery. Din fericire, jQuery acceptă majoritatea selectoarelor CSS3, ceea ce facilitează preluarea elementelor din DOM. Aruncă o privire la următorul cod:

 $("#container");

În blocul de cod de mai sus, jQuery selectează elementele cu id-ul „container”. O implementare similară folosind JavaScript vechi obișnuit ar arăta cam așa:

 document.querySelectorAll("#container");

Comparând ultimele două blocuri de cod, puteți vedea că fostul bloc de cod este mult mai ușor de citit decât cel din urmă. Aceasta este frumusețea jQuery.

jQuery are, de asemenea, metode utile precum text(), html() și multe altele care fac posibilă manipularea elementelor HTML. Există mai multe metode pe care le puteți folosi pentru a traversa DOM, cum ar fi parent(), siblings(), prev() și next().

Metoda each() din jQuery este foarte populară în multe proiecte Cheerio. Vă permite să iterați peste obiecte și matrice. Sintaxa pentru metoda each() arată astfel:

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

În blocul de cod de mai sus, apel invers rulează pentru fiecare iterație a matricei sau a argumentului obiectului.

  Platform Engineering vs DevOps: prin ce diferă?

Se încarcă HTML cu Cheerio

Pentru a începe analizarea datelor HTML sau XML cu Cheerio, puteți utiliza metoda cheerio.load(). Aruncă o privire la acest exemplu:

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

Acest bloc de cod folosește metoda jQuery text() pentru a extrage conținutul text al elementului h1. Sintaxa completă pentru metoda load() arată astfel:

 load(content, options, mode)

Parametrul de conținut se referă la datele HTML sau XML reale pe care le transmiteți metoda load(). opțiuni este un obiect opțional care poate modifica comportamentul metodei. În mod implicit, metoda load() introduce elemente html, head și body dacă acestea lipsesc. Dacă doriți să opriți acest comportament, asigurați-vă că ați setat modul la false.

Scraping Hacker News With Cheerio

Codul folosit în acest proiect este disponibil în a Depozitul GitHub și este gratuit pentru utilizare sub licența MIT.

Este timpul să combinați tot ce ați învățat până acum și să creați un simplu web scraper. Hacker News este un site web popular pentru antreprenori și inovatori. Este, de asemenea, un site perfect pentru a vă valorifica abilitățile de scraping web, deoarece se încarcă rapid, are o interfață foarte simplă și nu difuzează reclame.

Asigurați-vă că aveți Node.js și Managerul de pachete Node care rulează pe mașina dvs. Creați un folder gol, apoi un fișier package.json și adăugați următorul JSON în interiorul fișierului:

 {
  "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"
  }
}

După ce faceți asta, deschideți terminalul și rulați:

 npm i

Acest lucru ar trebui să instaleze dependențele necesare de care aveți nevoie pentru a construi scraperul. Aceste pachete includ Cheerio pentru analiza HTML, ExpressJS pentru crearea serverului și, ca dependență de dezvoltare, Nodemon, un utilitar care ascultă modificările din proiect și repornește automat serverul.

Configurarea lucrurilor și crearea funcțiilor necesare

Creați un fișier index.js și, în acel fișier, creați o variabilă constantă numită „PORT”. Setați PORT la 5500 (sau orice număr alegeți), apoi importați pachetele Cheerio și, respectiv, Express.

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

Apoi, definiți trei variabile: url, html și finishedPage. Setați adresa URL la adresa URL a Hacker News.

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

Acum creați o funcție numită getHeader() care returnează niște coduri HTML pe care browserul ar trebui să îl redeze.

 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>
`}

Creați o altă funcție getScript() care returnează JavaScript pentru ca browserul să ruleze. Asigurați-vă că treceți tipul de variabilă ca argument atunci când îl apelați.

 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>`
}

În cele din urmă, creați o funcție asincronă numită fetchAndRenderPage(). Această funcție face exact ceea ce crezi: răzuiește o pagină în Hacker News, o analizează și o formatează cu Cheerio, apoi trimite niște HTML înapoi clientului pentru randare.

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

Pe Hacker News, există diferite tipuri de postări disponibile. Există „știrile”, care sunt lucrurile de pe prima pagină, postările care caută răspunsuri de la alți membri ai Hacker News au eticheta „întreaba”. Postările în tendințe au eticheta „cel mai bun”, cele mai recente postări au eticheta „cele mai noi”, iar postările referitoare la locurile de muncă vacante au eticheta „locuri de muncă”.

  Aveți nevoie de un cont Zoom pentru a participa la o întâlnire

fetchAndRenderPage() preia lista de postări din pagina Hacker News pe baza tipului pe care îl transmiteți ca argument. Dacă operația de preluare are succes, funcția leagă variabila html la textul de răspuns.

Apoi, adăugați următoarele linii la funcție:

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

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

În blocul de cod de mai sus, metoda set() setează câmpul antet HTTP. Metoda write() este responsabilă pentru trimiterea unei părți din corpul răspunsului. Funcția load() ia ca argument html.

Apoi, adăugați următoarele linii pentru a selecta copiii respectivi ai tuturor elementelor cu clasa „titleline”.

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

În acest bloc de cod, fiecare iterație preia conținutul text al elementului HTML țintă și îl stochează în variabila titlu.

Apoi, împingeți răspunsul de la funcția getScript() în matricea articole. Apoi creați o variabilă, finishedPage, care va reține HTML-ul final pentru a fi trimis în browser. În cele din urmă, utilizați metoda write() pentru a trimite finishedPage ca o bucată și pentru a încheia procesul de răspuns cu metoda end().

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

Definirea rutelor pentru a gestiona cererile GET

Chiar sub funcția fetchAndRenderPage, utilizați metoda express get() pentru a defini rutele respective pentru diferite tipuri de postări. Apoi utilizați metoda de ascultare pentru a asculta conexiunile la portul specificat din rețeaua locală.

 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)

În blocul de cod de mai sus, fiecare metodă get are o funcție de apel invers care apelează funcția fetchAndRenderPage, pasând în tipurile respective și obiectele res.

  Lucrand de acasa? 5 moduri de a-ți arăta PC-ului tău puțină dragoste

Când deschideți terminalul și rulați npm run start. Serverul ar trebui să pornească, apoi puteți vizita localhost:5500 în browser pentru a vedea rezultatele.

Felicitări, tocmai ați reușit să răzuiți Hacker News și să preluați titlurile postărilor fără a fi nevoie de un API extern.

Ducând lucrurile mai departe cu Web Scraping

Cu datele pe care le extrageți din Hacker News, puteți crea diverse vizualizări, cum ar fi diagrame, grafice și nori de cuvinte pentru a prezenta perspective și tendințe într-un format mai ușor de digerat.

De asemenea, puteți analiza profilurile utilizatorilor pentru a analiza reputația utilizatorilor de pe platformă pe baza unor factori precum voturile primite, comentariile făcute și altele.