Verkkosivuston kaapiminen Node.js:n ja Puppeteerin avulla | DigitalOcean (2023)

Kirjoittaja valitsiIlmainen ja avoimen lähdekoodin rahastovastaanottaa lahjoituksen osanaKirjoita lahjoituksia vartenohjelmoida.

Johdanto

Web-kaappaus on prosessi, jolla automatisoidaan tiedonkeruu verkosta. Prosessi käyttää tyypillisesti "indeksointirobottia", joka surffaa automaattisesti verkossa ja kerää tietoja valituilta sivuilta. On monia syitä, miksi saatat haluta kaapata tietoja. Ensisijaisesti se nopeuttaa tiedonkeruuta huomattavasti eliminoimalla manuaalisen tiedonkeruun. Kaapiminen on ratkaisu myös silloin, kun tiedonkeruuta halutaan tai tarvitaan, mutta sivusto ei tarjoa APIa.

Tässä opetusohjelmassa rakennat verkkokaappaussovelluksen käyttämälläNode.jsjaNukkenäyttelijä. Sovelluksesi monimutkaisuus kasvaa edistyessäsi. Ensin koodaat sovelluksesi avautuvaksiKromija lataa erityinen verkkosivusto, joka on suunniteltu verkkoa kaapivaksi hiekkalaatikoksi:books.toscrape.com. Kahdessa seuraavassa vaiheessa kaikki kirjat kaavitaan yhdelle books.toscrape-sivulle ja sitten kaikki kirjat useille sivuille. Muissa vaiheissa suodatat kaavinta kirjaluokan mukaan ja tallennat sitten tietosi JSON-tiedostona.

Varoitus:Verkkokaappauksen etiikka ja laillisuus ovat erittäin monimutkaisia ​​ja kehittyvät jatkuvasti. Ne vaihtelevat myös sijaintisi, tietojen sijainnin ja kyseessä olevan verkkosivuston mukaan. Tämä opetusohjelma kaappaa erityisen verkkosivuston,books.toscrape.com, joka on erityisesti suunniteltu kaavinsovellusten testaamiseen.Minkä tahansa muun verkkotunnuksen kaapiminen ei kuulu tämän opetusohjelman piiriin.

Edellytykset

  • Node.js asennettuna kehityskoneellesi. Tämä opetusohjelma on testattu Node.js-versiolla 12.18.3 ja npm-versiolla 6.14.6.Voit noudattaa tätä opasta asentaaksesi Node.js:n macOS- tai Ubuntu 18.04:ään, tai voitseuraa tätä opasta asentaaksesi Node.js Ubuntu 18.04:ään PPA:n avulla.

Vaihe 1 – Web Scraperin määrittäminen

Kun Node.js on asennettu, voit aloittaa verkkokaavin asennuksen. Ensin luot projektin juurihakemiston ja asennat sitten tarvittavat riippuvuudet. Tämä opetusohjelma vaatii vain yhden riippuvuuden, ja asennat sen käyttämällä Node.js:n oletuspakettien hallintaanpm. npm tulee esiasennettuna Node.js:n kanssa, joten sinun ei tarvitse asentaa sitä.

Luo kansio tälle projektille ja siirry sitten sisään:

  1. mkdirkirjakaavin
  2. CDkirjakaavin

Suoritat kaikki seuraavat komennot tästä hakemistosta.

Meidän on asennettava yksi paketti npm:n tai solmun pakettien hallinnan avulla. Alusta ensin npm, jotta voit luoda apackages.jsontiedosto, joka hallitsee projektisi riippuvuuksia ja metatietoja.

Alusta npm projektillesi:

  1. npmsen sisällä

npm esittää kehotteiden sarjan. Voit painaaTULLA SISÄÄNjokaiseen kehotteeseen tai voit lisätä mukautettuja kuvauksia. Muista painaaTULLA SISÄÄNja jätä oletusarvot paikoilleen pyydettäessäsisääntulopiste:jatesti komento:. Vaihtoehtoisesti voit ohittaayliputtaanpmnpm init -y– ja se lähettää kaikki oletusarvot puolestasi.

Tulostuksesi näyttää suunnilleen tältä:

Lähtö

{ "nimi": "sammy_scraper", "versio": "1.0.0", "kuvaus": "verkkokaavin", "main": "index.js", "skriptit": { "testi": "echo \"Virhe: testiä ei määritetty\" && exit 1" }, "keywords": [], "author": "sammy hai", "lisenssi": "ISC"}Onko tämä ok? (kyllä ​​kyllä

TyyppiJooja painaTULLA SISÄÄN. npm tallentaa tämän tulosteen sinunpackage.jsontiedosto.

Käytä nyt npm:ää Puppeteerin asentamiseen:

  1. npm Asentaa --Tallentaanukkenäyttelijä

Tämä komento asentaa sekä Puppeteerin että Chromiumin version, jonka Puppeteer-tiimi tietää toimivan niiden API:n kanssa.

Linux-koneissa Puppeteer saattaa vaatia joitain lisäriippuvuuksia.

Jos käytät Ubuntu 18.04:ää,tarkista Puppeteerin vianmääritysdokumenttien Debian-riippuvuudet-valikko kohdasta "Chrome headless ei käynnisty UNIXissa". Voit käyttää seuraavaa komentoa puuttuvien riippuvuuksien löytämiseen:

  1. ldd kromi| grepei

Kun npm, Puppeteer ja kaikki muut riippuvuudet on asennettu, sinunpackage.jsontiedosto vaatii viimeisen konfiguroinnin ennen koodauksen aloittamista. Tässä opetusohjelmassa käynnistät sovelluksesi komentoriviltänpm ajon aloitus. Sinun on lisättävä tietoja tästäalkaakäsikirjoittaapackage.json. Erityisesti sinun on lisättävä yksi rivi -kohdan allekäsikirjoituksiaohje koskien sinuaalkaakomento.

Avaa tiedosto haluamassasi tekstieditorissa:

  1. nanopackage.json

Etsikäsikirjoitukset:-osio ja lisää seuraavat kokoonpanot. Muista laittaa pilkku merkin loppuuntestatakomentosarja, tai tiedostosi ei jäsenny oikein.

Lähtö

{ . . . "scripts": { "test": "echo \"Virhe: testiä ei määritetty\" && poistu 1","start": "node index.js"}, . . . "riippuvuudet": { "nukkenäyttelijä": "^5.2.1" }}

Huomaat myös sennukkenäyttelijänäkyy nyt allariippuvuuksialähellä tiedoston loppua. Sinunpackage.jsontiedosto ei vaadi enempää muutoksia. Tallenna muutokset ja sulje editori.

Olet nyt valmis aloittamaan kaavin koodauksen. Seuraavassa vaiheessa määrität selainesiintymän ja testaat kaavin perustoiminnallisuutta.

Vaihe 2 – Selainesiintymän määrittäminen

Kun avaat perinteisen selaimen, voit esimerkiksi napsauttaa painikkeita, navigoida hiirellä, kirjoittaa, avata kehitystyökaluja ja paljon muuta. Chromiumin kaltaisella päättömällä selaimella voit tehdä nämä samat asiat, mutta ohjelmallisesti ja ilman käyttöliittymää. Tässä vaiheessa määrität kaavin selainesiintymän. Kun käynnistät sovelluksesi, se avaa automaattisesti Chromiumin ja siirtyy kohteeseenbooks.toscrape.com. Nämä ensimmäiset toimet muodostavat ohjelmasi perustan.

Verkkokaavin tarvitsee neljä.jstiedostot:browser.js,indeksi, js,pageController.js, japageScraper.js. Tässä vaiheessa luot kaikki neljä tiedostoa ja päivität niitä sitten jatkuvasti, kun ohjelmasi kehittyy. Aloitabrowser.js; tämä tiedosto sisältää komentosarjan, joka käynnistää selaimesi.

Luo ja avaa projektisi juurihakemistostabrowser.jstekstieditorissa:

  1. nanobrowser.js

Ensinnäkin teetvaatiaNukketeatteri ja luo sittenasynkkutsuttu toimintostartBrowser(). Tämä toiminto käynnistää selaimen ja palauttaa sen esiintymän. Lisää seuraava koodi:

./book-scraper/browser.js

konstnukkenäyttelijä= vaatia("nukkenäyttelijä");asynk toiminto startBrowser(){antaaselain;yrittää {konsoli.Hirsi("Avaa selain......");selain= odottaanukkenäyttelijä.tuoda markkinoille({ päätön: väärä, args: ["--disable-setuid-sandbox"], 'ignoreHTTPSErrors': totta });} ottaa kiinni (err) {konsoli.Hirsi("Selaininstanssia ei voitu luoda => :",err);}palataselain;}moduuli.vientiä= {startBrowser};

Nukketeatterilla on a.tuoda markkinoille()menetelmäjoka käynnistää selaimen esiintymän. Tämä menetelmä palauttaa aLupaus, joten sinun täytyyvarmista, että lupaus ratkeaa käyttämällä a.sittentaiodottaalohko.

Käytätodottaavarmistaaksesi, että lupaus ratkeaa, käärimällä tämän tapauksen ympärilleayritä saada kiinnikoodilohkoja palauttaa sitten selaimen esiintymän.

Huomaa, että.tuoda markkinoille()menetelmä ottaa JSON-parametrin, jolla on useita arvoja:

  • päätön-väärätarkoittaa, että selain toimii käyttöliittymän kanssa, jotta voit katsella skriptin suorittamista samallatottatarkoittaa, että selain toimii päättömässä tilassa. Huomaa kuitenkin, että jos haluat ottaa kaavin käyttöön pilvessä, määritäpäätöntakaisintotta. Useimmat virtuaalikoneet ovat päättömiä eivätkä sisällä käyttöliittymää, joten ne voivat käyttää selainta vain päättömässä tilassa. Nukketeatteri sisältää myös apäättäväinen-tilassa, mutta sitä tulisi käyttää vain testaustarkoituksiin.
  • ohita HTTPSEvirheet-tottaVoit vierailla verkkosivustoilla, joita ei isännöidä suojatun HTTPS-protokollan kautta, ja jättää huomioimatta kaikki HTTPS-virheet.

Tallenna ja sulje tiedosto.

Luo nyt toinen.jstiedosto,index.js:

  1. nanoindex.js

Tässä tuletvaatia browser.jsjapageController.js. Soitat sittenstartBrowser()toiminto ja välitä luotu selainesiintymä sivun ohjaimelle, joka ohjaa sen toimia. Lisää seuraava koodi:

./book-scraper/index.js

konstselainobjekti= vaatia('./selain');konstscraperController= vaatia('./pageController');//Käynnistä selain ja luo selainesiintymäantaaselainInstance=selainobjekti.startBrowser();// Välitä selaimen ilmentymä kaavinohjaimellescraperController(selainInstance)

Tallenna ja sulje tiedosto.

Luo kolmas.jstiedosto,pageController.js:

  1. nanopageController.js

pageController.jshallitsee kaavintaprosessiasi. Se käyttää selaimen ilmentymää hallitsemaanpageScraper.jstiedosto, jossa kaikki kaavintavat komentosarjat suoritetaan. Lopulta käytät sitä määrittämään, minkä kirjaluokan haluat kaapia. Toistaiseksi haluat kuitenkin vain varmistaa, että voit avata Chromiumin ja navigoida verkkosivulle:

./book-scraper/pageController.js

konstsivukaavin= vaatia('./pageScraper');asynk toiminto scrapeAll(selainInstance){antaaselain;yrittää{selain= odottaaselainInstance;odottaasivukaavin.kaavin(selain);}ottaa kiinni(err){konsoli.Hirsi("Selaininstanssia ei voitu ratkaista =>",err);}}moduuli.vientiä = (selainInstance) => scrapeAll(selainInstance)

Tämä koodi vie funktion, joka ottaa selaimen ilmentymän ja välittää sen funktiolle, jota kutsutaanscrapeAll(). Tämä toiminto puolestaan ​​välittää tämän ilmentymänpageScraper.scraper()argumenttina, joka käyttää sitä sivujen kaappaamiseen.

Tallenna ja sulje tiedosto.

Lopuksi luo viimeinen.jstiedosto,pageScraper.js:

  1. nanopageScraper.js

Täällä luot objektin kirjaimella aurlomaisuus ja akaavin()menetelmä. Theurlon sen verkkosivun URL-osoite, jonka haluat kaapata, kun taaskaavin()menetelmä sisältää koodin, joka suorittaa varsinaisen kaavin, vaikka tässä vaiheessa se vain navigoi URL-osoitteeseen. Lisää seuraava koodi:

./book-scraper/pageScraper.js

konstscraperObject= {url: "http://books.toscrape.com",asynk kaavin(selain){antaasivu= odottaaselain.uusi sivu();konsoli.Hirsi(`Navigoidaan kohteeseen${Tämä.url}...`);odottaasivu.mene(Tämä.url);}}moduuli.vientiä=scraperObject;

Nukketeatterilla on auusi sivu()menetelmäjoka luo uuden sivun ilmentymän selaimeen, ja nämä sivuesiintymät voivat tehdä melko monia asioita. Meidänkaavin()-menetelmällä, loit sivuesiintymän ja käytit sittenpage.goto()menetelmänavigoidaksesi kohteeseenbooks.toscrape.com-kotisivulla.

Tallenna ja sulje tiedosto.

Ohjelmasi tiedostorakenne on nyt valmis. Projektisi hakemistopuun ensimmäinen taso näyttää tältä:

Lähtö

.├── browser.js├── index.js├── node_modules├── package-lock.json├── package.json├── pageController.js└── pageScraper.

Suorita nyt komentonpm ajon aloitusja katso kaavinsovelluksesi suorittavan:

  1. npmjuoksun aloitus

Se avaa automaattisesti Chromium-selainesiintymän, avaa uuden sivun selaimessa ja siirtyy kohtaanbooks.toscrape.com.

Tässä vaiheessa loit Puppeteer-sovelluksen, joka avasi Chromiumin ja latasi näennäisen verkkokirjakaupan -books.toscrape.com -kotisivun. Seuraavassa vaiheessa raaputat jokaisen etusivun kirjan tiedot.

Vaihe 3 – Tietojen kaapiminen yhdeltä sivulta

Ennen kuin lisäät toimintoja kaavinsovellukseesi, avaa haluamasi verkkoselain ja siirry manuaalisesti kohtaankirjoja kotisivuille. Selaa sivustoa ja saat käsityksen tietojen rakenteesta.

Verkkosivuston kaapiminen Node.js:n ja Puppeteerin avulla | DigitalOcean (1)

Vasemmalla on kategoriaosio ja oikealla kirjat. Kun napsautat kirjaa, selain siirtyy uuteen URL-osoitteeseen, joka näyttää oleelliset tiedot kyseisestä kirjasta.

Tässä vaiheessa kopioit tämän toiminnan, mutta koodilla; automatisoit verkkosivustolla liikkumisen ja sen tietojen kulutuksen.

Ensinnäkin, jos tarkastat kotisivun lähdekoodin selaimen Dev Tools -työkalujen avulla, huomaat, että sivulla luetellaan jokaisen kirjan tiedotosiotag. Sisälläosiotunniste jokainen kirja on alla alista(li) -tunnisteen, ja täältä löydät linkin kirjan omalle sivulle, hinnan ja saatavuuden varastossa.

Verkkosivuston kaapiminen Node.js:n ja Puppeteerin avulla | DigitalOcean (2)

Kaaviat näiden kirjojen URL-osoitteet, suodatat varastossa olevat kirjat, siirryt kullekin yksittäiselle kirjan sivulle ja keräät kirjan tiedot.

Avaa uudelleenpageScraper.jstiedosto:

  1. nanopageScraper.js

Lisää seuraava korostettu sisältö. Pesät toisenodottaalohko sisälläodota page.goto(this.url);:

./book-scraper/pageScraper.js

konstscraperObject= { url: "http://books.toscrape.com", asynk kaavin(selain){ antaasivu= odottaaselain.uusi sivu();konsoli.Hirsi(`Navigoidaan kohteeseen${Tämä.url}...`);// Navigoi valitulle sivulleodottaasivu.mene(Tämä.url);// Odota, että vaadittu DOM renderöidäänodottaasivu.odotaValitsijaa('.page_inner');// Hanki linkki kaikkiin tarvittaviin kirjoihinantaaURL-osoitteet= odottaasivu.$$eval('section ol > li', linkkejä => {// Varmista, että kaavittava kirja on varastossalinkkejä=linkkejä.suodattaa(linkki =>linkki.querySelector('.instock.availability > i').tekstisisältö!== "Varastossa")// Pura linkit tiedoistalinkkejä=linkkejä.kartta(hän =>hän.querySelector('h3 > a').href)palatalinkkejä;});konsoli.Hirsi(URL-osoitteet); }}moduuli.vientiä=scraperObject;

Tässä koodilohkossa soititthepage.waitForSelector()menetelmä. Tämä odotti, että div, joka sisältää kaikki kirjaan liittyvät tiedot, renderöitiin DOM:ssa, ja sitten soititthesivu.$$eval()menetelmä. Tämä menetelmä saa URL-elementin valitsimella§ ol li(varmista, että palautat aina vain merkkijonon tai numeronsivu.$eval()jasivu.$$eval()menetelmät).

Jokaisella kirjalla on kaksi tilaa; kirja on jokoVarastossataiLoppu varastosta. Haluat vain raapia kirjoja, jotka ovatVarastossa. Koskasivu.$$eval()palauttaa joukon kaikkia vastaavia elementtejä, olet suodattanut tämän taulukon varmistaaksesi, että työskentelet vain varastossa olevien kirjojen kanssa. Teit tämän etsimällä ja arvioimalla luokkaa.varastossa.saatavuus. Sitten kartoitithrefkirjalinkkien omaisuutta ja palautti sen menetelmästä.

Tallenna ja sulje tiedosto.

Suorita sovelluksesi uudelleen:

  1. npmjuoksun aloitus

Selain avautuu, siirtyy verkkosivulle ja sulkeutuu, kun tehtävä on valmis. Tarkista nyt konsoli; se sisältää kaikki kopioidut URL-osoitteet:

Lähtö

> book-scraper@1.0.0 start/Users/sammy/book-scraper> node index.jsAvaa selain......Siirry osoitteeseen http://books.toscrape.com...[ 'http://books.toscrape.com/catalogue/a-light-in-the-attic_1000 /index.html", "http://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html", "http://books.toscrape.com/catalogue/soumission_998/index.html", 'http://books.toscrape.com/catalogue/sharp-objects_997/index.html', 'http://books.toscrape.com/catalogue/sapiens-a-brief-history-of-humankind_996/index.html ', 'http://books.toscrape.com/catalogue/the-requiem-red_995/index.html', 'http://books.toscrape.com/catalogue/the-dirty-little-secrets-of-getting -your-dream-job_994/index.html", "http://books.toscrape.com/catalogue/the-coming-woman-a-novel-based-on-the-life-of-the-infamous-feminist -victoria-woodhull_993/index.html", "http://books.toscrape.com/catalogue/the-boys-in-the-boat-nine-americans-and-their-epic-quest-for-gold-at" -the-1936-berlin-olympics_992/index.html", "http://books.toscrape.com/catalogue/the-black-maria_991/index.html", "http://books.toscrape.com/catalogue" /starving-hearts-triangular-trade-trilogy-1_990/index.html", "http://books.toscrape.com/catalogue/shakespeares-sonnets_989/index.html", "http://books.toscrape.com" /catalogue/set-me-free_988/index.html", "http://books.toscrape.com/catalogue/scott-pilgrims-precious-little-life-scott-pilgrim-1_987/index.html", "http:// ://books.toscrape.com/catalogue/rip-it-up-and-start-again_986/index.html", "http://books.toscrape.com/catalogue/our-band-could-be-your -life-scenes-from-the-american-indie-underground-1981-1991_985/index.html", "http://books.toscrape.com/catalogue/olio_984/index.html", "http://books" .toscrape.com/catalogue/mesaerion-the-best-science-fiction-stories-1800-1849_983/index.html", "http://books.toscrape.com/catalogue/libertarianism-for-beginners_982/index.html" ', 'http://books.toscrape.com/catalogue/its-only-the-himalayas_981/index.html']

Tämä on loistava alku, mutta haluat kaapata kaikki tietyn kirjan olennaiset tiedot, ei vain sen URL-osoitetta. Käytät nyt näitä URL-osoitteita jokaisen sivun avaamiseen ja kirjan nimen, tekijän, hinnan, saatavuuden, UPC:n, kuvauksen ja kuvan URL-osoitteen keräämiseen.

Avaa uudelleenpageScraper.js:

  1. nanopageScraper.js

Lisää seuraava koodi, joka käy läpi jokaisen kaavitun linkin, avaa uuden sivun esiintymän ja noutaa sitten tarvittavat tiedot:

./book-scraper/pageScraper.js

konstscraperObject= { url: "http://books.toscrape.com", asynk kaavin(selain){ antaasivu= odottaaselain.uusi sivu();konsoli.Hirsi(`Navigoidaan kohteeseen${Tämä.url}...`);// Navigoi valitulle sivulleodottaasivu.mene(Tämä.url);// Odota, että vaadittu DOM renderöidäänodottaasivu.odotaValitsijaa('.page_inner');// Hanki linkki kaikkiin tarvittaviin kirjoihinantaaURL-osoitteet= odottaasivu.$$eval('section ol > li', linkkejä => {// Varmista, että kaavittava kirja on varastossalinkkejä=linkkejä.suodattaa(linkki =>linkki.querySelector('.instock.availability > i').tekstisisältö!== "Varastossa")// Pura linkit tiedoistalinkkejä=linkkejä.kartta(hän =>hän.querySelector('h3 > a').href)palatalinkkejä;}); // Selaa jokaisen linkin läpi, avaa uusi sivuinstanssi ja hanki niistä tarvittavat tiedotantaa sivu Lupaus = (linkki) => Uusi Lupaus(asynk(ratkaista,hylätä) => {antaadataObj= {};antaauusi sivu= odottaaselain.uusi sivu();odottaauusi sivu.mene(linkki);dataObj['kirjan nimi'] = odottaauusi sivu.$eval(".product_main > h1", teksti =>teksti.tekstisisältö);dataObj['bookPrice'] = odottaauusi sivu.$eval(".price_color", teksti =>teksti.tekstisisältö);dataObj['ei saatavilla'] = odottaauusi sivu.$eval('.varasto.saatavuus', teksti => {// Poista uudet rivi- ja sarkainvälitteksti=teksti.tekstisisältö.korvata(/(\r\n\t|\n|\r|\t)/gm, "");// Hanki käytettävissä olevien varastojen määräantaaregexp= /^.*\((.*)\).*$/i;antaavarastossa saatavilla=regexp.exec(teksti)[1].jakaa('')[0];palatavarastossa saatavilla;});dataObj['imageUrl'] = odottaauusi sivu.$eval("#product_gallery img", img =>img.src);dataObj['bookDescription'] = odottaauusi sivu.$eval('#Tuotteen Kuvaus', div =>div.seuraava sisarus.seuraava sisarus.tekstisisältö);dataObj['upc'] = odottaauusi sivu.$eval('.table.table-striped > tbody > tr > td', pöytä =>pöytä.tekstisisältö);ratkaista(dataObj);odottaauusi sivu.kiinni();});varten(linkkisisäänURL-osoitteet){antaaCurrentPageData= odottaa sivu Lupaus(URL-osoitteet[linkki]);// scrapedData.push(currentPageData);konsoli.Hirsi(CurrentPageData);} }}moduuli.vientiä=scraperObject; 

Sinulla on joukko kaikkia URL-osoitteita. Haluat käydä läpi tämän taulukon, avata URL-osoitteen uudella sivulla, kaapata tietoja kyseiseltä sivulta, sulkea sivu ja avata uuden sivun taulukon seuraavaa URL-osoitetta varten. Huomaa, että käärit tämän koodin lupaukseen. Tämä johtuu siitä, että haluat odottaa jokaisen silmukan toiminnon valmistumista. Siksi jokainen lupaus avaa uuden URL-osoitteen, eikä se ratkea ennen kuin ohjelma on raapunut kaikki URL-osoitteen tiedot ja sitten sivun esiintymä on suljettu.

Varoitus:Huomaa hyvin, että odotit lupausta käyttämällä asisäänsilmukka. Mikä tahansa muu silmukka riittää, mutta vältä iteroimista URL-taulukoiden yli käyttämällä taulukkoiterointimenetelmää, kutenjokaiselle, tai mikä tahansa muu menetelmä, joka käyttää takaisinsoittotoimintoa. Tämä johtuu siitä, että takaisinsoittotoiminnon on käytävä ensin takaisinsoittojonon ja tapahtumasilmukan läpi, joten useat sivun esiintymät avautuvat kerralla. Tämä rasittaa paljon enemmän muistiasi.

Katso tarkemmin omaasisivu Lupaustoiminto. Kaavin loi ensin uuden sivun jokaiselle URL-osoitteelle ja käytit sittensivu.$eval()-toiminto kohdistaa valitsijoihin asiaankuuluviin yksityiskohtiin, jotka halusit kaapata uudelle sivulle. Jotkut tekstit sisältävät välilyöntejä, sarkaimia, rivinvaihtoja ja muita ei-aakkosnumeerisia merkkejä, jotka olet poistanut säännöllisellä lausekkeella. Lisäsit sitten jokaisen tällä sivulla kaavitun datan arvon objektiin ja ratkaisit kyseisen objektin.

Tallenna ja sulje tiedosto.

Suorita skripti uudelleen:

  1. npmjuoksun aloitus

Selain avaa kotisivun ja avaa sitten jokaisen kirjan sivun ja kirjaa kaavitut tiedot jokaiselta sivulta. Tämä tulos tulostuu konsoliisi:

Lähtö

Selaimen avaaminen......Siirrytään osoitteeseen http://books.toscrape.com...{ bookTitle: 'A Light in the Attic', bookHinta: '51,77 £, eiSaatavilla: '22', imageUrl: ' http://books.toscrape.com/media/cache/fe/72/fe72f0532301ec28892ae79a629a293c.jpg', bookDescription: "On vaikea kuvitella maailmaa ilman valoa ullakolla. [...]", upc: 'a897fe39b2153 '}{ bookTitle: 'Tipping the Velvet', bookHinta: '53,74 puntaa', eiSaatavilla: '20', imageUrl: 'http://books.toscrape.com/media/cache/08/e9/08e94f3731d7d6b760dfca'5. bookDescription: `"Eroottinen ja kottainen...Kirjoitettu kottaraisen voimalla."--"New York Timesin kirja-arvostelu" Nan King, osterityttö, kiehtoo musiikkihalli-ilmiötä Kitty Butler [...]`, upc : '90FA61229261140A'} {BookTitle: 'Soumission', BookPrice: '£ 50.10', Noavable: '20', ImageUrl: 'http://books.toscrape.com/media/cache/ee/cf/eecfe998905E455df12064dba399c075.jpg' , bookDescription: 'Dans une France assez proche de la nôtre, [...]', upc: '6957f44c3847a760'}...

Tässä vaiheessa keräsit tarvittavat tiedot jokaisesta kirjan etusivultabooks.toscrape.com, mutta voit lisätä paljon enemmän toimintoja. Esimerkiksi kirjojen jokainen sivu on sivuttu; miten saat kirjoja näiltä muilta sivuilta? Lisäksi sivuston vasemmasta reunasta löysit kirjaluokkia; entä jos et halua kaikkia kirjoja, mutta haluat vain kirjoja tietystä genrestä? Lisäät nyt nämä ominaisuudet.

Vaihe 4 – Tietojen kaapiminen useilta sivuilta

Sivut päälläbooks.toscrape.comsivutuissa on aSeuraava-painiketta sisällön alla, kun taas sivut, joita ei ole sivutettu, eivät.

Tämän painikkeen avulla voit määrittää, onko sivu sivutettu vai ei. Koska jokaisen sivun tiedot ovat rakenteeltaan samanlaisia ​​ja niissä on samat merkinnät, et kirjoita kaavinta jokaiselle mahdolliselle sivulle. Sen sijaan käytät käytäntöärekursio.

Ensin sinun on muutettava koodisi rakennetta hieman, jotta voit siirtyä rekursiivisesti useille sivuille.

Avaa uudelleenpagescraper.js:

  1. nanopagescraper.js

Lisäät uuden toiminnon nimeltäscrapeCurrentPage()sinunkaavin()menetelmä. Tämä toiminto sisältää kaiken koodin, joka kerää tietoja tietystä sivusta ja napsauta sitten seuraavaa painiketta, jos se on olemassa. Lisää seuraava korostettu koodi:

./book-scraper/pageScraper.js scraper()

konstscraperObject= { url: "http://books.toscrape.com", asynk kaavin(selain){antaasivu= odottaaselain.uusi sivu();konsoli.Hirsi(`Navigoidaan kohteeseen${Tämä.url}...`);// Navigoi valitulle sivulleodottaasivu.mene(Tämä.url);antaascrapedData= [];// Odota, että vaadittu DOM renderöidäänasynk toiminto scrapeCurrentPage(){odottaasivu.odotaValitsijaa('.page_inner');// Hanki linkki kaikkiin tarvittaviin kirjoihinantaaURL-osoitteet= odottaasivu.$$eval('section ol > li', linkkejä => {// Varmista, että kaavittava kirja on varastossalinkkejä=linkkejä.suodattaa(linkki =>linkki.querySelector('.instock.availability > i').tekstisisältö!== "Varastossa")// Pura linkit tiedoistalinkkejä=linkkejä.kartta(hän =>hän.querySelector('h3 > a').href)palatalinkkejä;});// Selaa jokaisen linkin läpi, avaa uusi sivuinstanssi ja hanki niistä tarvittavat tiedotantaa sivu Lupaus = (linkki) => Uusi Lupaus(asynk(ratkaista,hylätä) => {antaadataObj= {};antaauusi sivu= odottaaselain.uusi sivu();odottaauusi sivu.mene(linkki);dataObj['kirjan nimi'] = odottaauusi sivu.$eval(".product_main > h1", teksti =>teksti.tekstisisältö);dataObj['bookPrice'] = odottaauusi sivu.$eval(".price_color", teksti =>teksti.tekstisisältö);dataObj['ei saatavilla'] = odottaauusi sivu.$eval('.varasto.saatavuus', teksti => {// Poista uudet rivi- ja sarkainvälitteksti=teksti.tekstisisältö.korvata(/(\r\n\t|\n|\r|\t)/gm, "");// Hanki käytettävissä olevien varastojen määräantaaregexp= /^.*\((.*)\).*$/i;antaavarastossa saatavilla=regexp.exec(teksti)[1].jakaa('')[0];palatavarastossa saatavilla;});dataObj['imageUrl'] = odottaauusi sivu.$eval("#product_gallery img", img =>img.src);dataObj['bookDescription'] = odottaauusi sivu.$eval('#Tuotteen Kuvaus', div =>div.seuraava sisarus.seuraava sisarus.tekstisisältö);dataObj['upc'] = odottaauusi sivu.$eval('.table.table-striped > tbody > tr > td', pöytä =>pöytä.tekstisisältö);ratkaista(dataObj);odottaauusi sivu.kiinni();});varten(linkkisisäänURL-osoitteet){antaaCurrentPageData= odottaa sivu Lupaus(URL-osoitteet[linkki]);scrapedData.työntää(CurrentPageData);// console.log(currentPageData);}// Kun kaikki tämän sivun tiedot on valmis, napsauta Seuraava-painiketta ja aloita seuraavan sivun kaapiminen// Tarkistat ensin, onko tämä painike olemassa, jotta tiedät onko seuraava sivu todella olemassa.antaanextButtonExist= väärä;yrittää{konstnextButton= odottaasivu.$eval('.seuraava > a', a =>a.tekstisisältö);nextButtonExist= totta;}ottaa kiinni(err){nextButtonExist= väärä;}jos(nextButtonExist){odottaasivu.klikkaus('.seuraava > a');palata scrapeCurrentPage(); // Kutsu tätä funktiota rekursiivisesti}odottaasivu.kiinni();palatascrapedData;}antaatiedot= odottaa scrapeCurrentPage();konsoli.Hirsi(tiedot);palatatiedot;}}moduuli.vientiä=scraperObject;

Sinä asetatnextButtonExistmuuttujan arvoksi false aluksi ja tarkista sitten, onko painike olemassa. JosSeuraavapainike on olemassa, asetat itsenextButtonOn olemassatotottaja jatka napsauttamallaSeuraava-painiketta ja kutsu sitten tätä funktiota rekursiivisesti.

JosnextButtonOn olemassaon väärä, se palauttaascrapedDatajoukko tavalliseen tapaan.

Tallenna ja sulje tiedosto.

Suorita skripti uudelleen:

  1. npmjuoksun aloitus

Tämä saattaa kestää jonkin aikaa. sovelluksesi loppujen lopuksi kaappaa nyt tietoja yli 800 kirjasta. Sulje selain vapaasti tai painaCTRL + Cperuuttaaksesi prosessin.

Olet nyt maksimoinut kaapimesi ominaisuudet, mutta olet luonut uuden ongelman prosessissa. Nyt ongelma ei ole liian vähän, vaan liian paljon. Seuraavassa vaiheessa hienosäädät sovellustasi suodattaaksesi kaavintuksesi kirjakategorioiden mukaan.

Vaihe 5 – Tietojen kaapiminen luokan mukaan

Jos haluat kaapata tietoja luokittain, sinun on muokattava molempiapageScraper.jstiedosto ja sinunpageController.jstiedosto.

AvatapageController.jstekstieditorissa:

nano pageController.js

Soita kaavinta, jotta se raaputtaa vain matkakirjoja. Lisää seuraava koodi:

./book-scraper/pageController.js

konstsivukaavin= vaatia('./pageScraper');asynk toiminto scrapeAll(selainInstance){antaaselain;yrittää{selain= odottaaselainInstance;antaascrapedData= {};// Soita kaavin erilaisten kirjojen kaavittavaksiscrapedData['Matkustaa'] = odottaasivukaavin.kaavin(selain, 'Matkustaa');odottaaselain.kiinni();konsoli.Hirsi(scrapedData)}ottaa kiinni(err){konsoli.Hirsi("Selaininstanssia ei voitu ratkaista =>",err);}}moduuli.vientiä = (selainInstance) => scrapeAll(selainInstance)

Siirrät nyt kaksi parametria omaanpageScraper.scraper()menetelmä, jossa toinen parametri on kaavittavien kirjojen luokka, mikä tässä esimerkissä onMatkustaa. Mutta sinunpageScraper.jstiedosto ei vielä tunnista tätä parametria. Sinun on myös säädettävä tätä tiedostoa.

Tallenna ja sulje tiedosto.

AvatapageScraper.js:

  1. nanopageScraper.js

Lisää seuraava koodi, joka lisää luokkaparametrisi, siirry kyseiselle luokkasivulle ja aloita sitten sivuttujen tulosten kaapiminen:

./book-scraper/pageScraper.js

konstscraperObject= { url: "http://books.toscrape.com", asynk kaavin(selain,kategoria){ antaasivu= odottaaselain.uusi sivu();konsoli.Hirsi(`Navigoidaan kohteeseen${Tämä.url}...`); // Navigoi valitulle sivulle odottaasivu.mene(Tämä.url); // Valitse näytettävän kirjan luokkaantaavalittu luokka= odottaasivu.$$eval('.side_categories > ul > li > ul > li > a', (linkkejä,_kategoria) => {// Etsi elementtiä, jolla on vastaava tekstilinkkejä=linkkejä.kartta(a =>a.tekstisisältö.korvata(/(\r\n\t|\n|\r|\t|^\s|\s$|\B\s|\s\B)/gm, "") ===_kategoria?a: tyhjä);antaalinkki=linkkejä.suodattaa(tx =>tx!== tyhjä)[0];palatalinkki.href;},kategoria);// Navigoi valittuun luokkaanodottaasivu.mene(valittu luokka); antaascrapedData= []; // Odota, että vaadittu DOM renderöidään asynk toiminto scrapeCurrentPage(){ odottaasivu.odotaValitsijaa('.page_inner'); // Hanki linkki kaikkiin tarvittaviin kirjoihin antaaURL-osoitteet= odottaasivu.$$eval('section ol > li', linkkejä => { // Varmista, että kaavittava kirja on varastossalinkkejä=linkkejä.suodattaa(linkki =>linkki.querySelector('.instock.availability > i').tekstisisältö!== "Varastossa") // Pura linkit tiedoistalinkkejä=linkkejä.kartta(hän =>hän.querySelector('h3 > a').href) palatalinkkejä; }); // Selaa jokaisen linkin läpi, avaa uusi sivuinstanssi ja hanki niistä tarvittavat tiedot antaa sivu Lupaus = (linkki) => Uusi Lupaus(asynk(ratkaista,hylätä) => { antaadataObj= {}; antaauusi sivu= odottaaselain.uusi sivu(); odottaauusi sivu.mene(linkki);dataObj['kirjan nimi'] = odottaauusi sivu.$eval(".product_main > h1", teksti =>teksti.tekstisisältö);dataObj['bookPrice'] = odottaauusi sivu.$eval(".price_color", teksti =>teksti.tekstisisältö);dataObj['ei saatavilla'] = odottaauusi sivu.$eval('.varasto.saatavuus', teksti => { // Poista uudet rivi- ja sarkainvälitteksti=teksti.tekstisisältö.korvata(/(\r\n\t|\n|\r|\t)/gm, ""); // Hanki käytettävissä olevien varastojen määrä antaaregexp= /^.*\((.*)\).*$/i; antaavarastossa saatavilla=regexp.exec(teksti)[1].jakaa('')[0]; palatavarastossa saatavilla; });dataObj['imageUrl'] = odottaauusi sivu.$eval("#product_gallery img", img =>img.src);dataObj['bookDescription'] = odottaauusi sivu.$eval('#Tuotteen Kuvaus', div =>div.seuraava sisarus.seuraava sisarus.tekstisisältö);dataObj['upc'] = odottaauusi sivu.$eval('.table.table-striped > tbody > tr > td', pöytä =>pöytä.tekstisisältö); ratkaista(dataObj); odottaauusi sivu.kiinni(); }); varten(linkkisisäänURL-osoitteet){ antaaCurrentPageData= odottaa sivu Lupaus(URL-osoitteet[linkki]);scrapedData.työntää(CurrentPageData); // console.log(currentPageData); } // Kun kaikki tämän sivun tiedot on valmis, napsauta Seuraava-painiketta ja aloita seuraavan sivun kaapiminen // Tarkistat ensin, onko tämä painike olemassa, jotta tiedät onko seuraava sivu todella olemassa. antaanextButtonExist= väärä; yrittää{ konstnextButton= odottaasivu.$eval('.seuraava > a', a =>a.tekstisisältö);nextButtonExist= totta; } ottaa kiinni(err){nextButtonExist= väärä; } jos(nextButtonExist){ odottaasivu.klikkaus('.seuraava > a'); palata scrapeCurrentPage(); // Kutsu tätä funktiota rekursiivisesti } odottaasivu.kiinni(); palatascrapedData; } antaatiedot= odottaa scrapeCurrentPage();konsoli.Hirsi(tiedot); palatatiedot; }}moduuli.vientiä=scraperObject;

Tämä koodilohko käyttää antamaasi luokkaa saadakseen URL-osoitteen, jossa kyseisen luokan kirjat sijaitsevat.

Thesivu.$$eval()voi ottaa argumentteja välittämällä argumentin kolmantena parametrina parametrille$$eval()menetelmää ja määrittämällä sen kolmanneksi parametriksi takaisinkutsussa:

esimerkkisivu.$$eval()-funktio

sivu.$$eval('valitsin', toiminto(elem,args){//.......},args)

Tämä oli mitä teit koodissasi; olet läpäissyt kirjojen luokan, jonka halusit kaapata, kartoittanut kaikki luokat tarkistaaksesi, mikä niistä vastaa, ja palautti sitten tämän luokan URL-osoitteen.

Tätä URL-osoitetta käytetään sitten siirtymiseen sivulle, joka näyttää kirjakategorian, jonka haluat kaapata käyttämälläpage.goto(selectedCategory)menetelmä.

Tallenna ja sulje tiedosto.

Suorita sovelluksesi uudelleen. Huomaat, että se siirtyy kohtaanMatkustaaluokka, avaa rekursiivisesti kyseisen luokan kirjoja sivu sivulta ja kirjaa tulokset lokiin:

  1. npmjuoksun aloitus

Tässä vaiheessa kaavisit tietoja useilta sivuilta ja sitten kaavisit tietoja useilta sivuilta yhdestä tietystä luokasta. Viimeisessä vaiheessa muokkaat skriptiäsi keräämään tietoja useista luokista ja tallennat sitten kopioidut tiedot ketjutettuun JSON-tiedostoon.

Vaihe 6 – Tietojen kerääminen useista luokista ja tietojen tallentaminen JSON-muodossa

Tässä viimeisessä vaiheessa annat skriptin raaputtaa tiedot pois niin monesta luokasta kuin haluat ja muutat sitten tulostustapaa. Tuloksia kirjaamisen sijaan tallennat ne jäsenneltyyn tiedostoon nimeltädata.json.

Voit lisätä nopeasti lisää luokkia kaavittavaksi; tämä vaatii vain yhden lisärivin genreä kohden.

AvatapageController.js:

  1. nanopageController.js

Muokkaa koodia lisäämään luokkia. Alla oleva esimerkki lisääHistoriallinen fiktiojaMysteeriolemassa olevaanMatkustaakategoria:

./book-scraper/pageController.js

konstsivukaavin= vaatia('./pageScraper');asynk toiminto scrapeAll(selainInstance){ antaaselain; yrittää{selain= odottaaselainInstance;antaascrapedData= {};// Soita kaavin erilaisten kirjojen kaavittavaksiscrapedData['Matkustaa'] = odottaasivukaavin.kaavin(selain, 'Matkustaa');scrapedData['Historiallinen fiktio'] = odottaasivukaavin.kaavin(selain, 'Historiallinen fiktio');scrapedData['Mysteeri'] = odottaasivukaavin.kaavin(selain, 'Mysteeri');odottaaselain.kiinni();konsoli.Hirsi(scrapedData)}ottaa kiinni(err){konsoli.Hirsi("Selaininstanssia ei voitu ratkaista =>",err);}}moduuli.vientiä = (selainInstance) => scrapeAll(selainInstance)

Tallenna ja sulje tiedosto.

Suorita skripti uudelleen ja katso, kuinka se kerää tietoja kaikista kolmesta kategoriasta:

  1. npmjuoksun aloitus

Kun kaavin on täysin toimiva, viimeinen vaihe on tietojen tallentaminen hyödyllisempään muotoon. Tallennat sen nyt JSON-tiedostoon käyttämälläthefsmoduuli Node.js:ssä.

Avaa ensin uudelleenpageController.js:

  1. nanopageController.js

Lisää seuraava korostettu koodi:

./book-scraper/pageController.js

konstsivukaavin= vaatia('./pageScraper');konstfs= vaatia('fs');asynk toiminto scrapeAll(selainInstance){antaaselain;yrittää{selain= odottaaselainInstance;antaascrapedData= {};// Soita kaavin erilaisten kirjojen kaavittavaksiscrapedData['Matkustaa'] = odottaasivukaavin.kaavin(selain, 'Matkustaa');scrapedData['Historiallinen fiktio'] = odottaasivukaavin.kaavin(selain, 'Historiallinen fiktio');scrapedData['Mysteeri'] = odottaasivukaavin.kaavin(selain, 'Mysteeri');odottaaselain.kiinni();fs.kirjoitustiedosto("data.json", JSON.kiristää(scrapedData), "utf8", toiminto(err) { jos(err) { palatakonsoli.Hirsi(err); } konsoli.Hirsi("Tiedot on kaavittu ja tallennettu onnistuneesti! Katso ne osoitteessa './data.json'");});}ottaa kiinni(err){konsoli.Hirsi("Selaininstanssia ei voitu ratkaista =>",err);}}moduuli.vientiä = (selainInstance) => scrapeAll(selainInstance)

Ensinnäkin tarvitset Node,js:nfsmoduuli sisäänpageController.js. Tämä varmistaa, että voit tallentaa tietosi JSON-tiedostona. Sitten lisäät koodia, jotta kun kaapiminen on valmis ja selain sulkeutuu, ohjelma luo uuden tiedoston nimeltädata.json. Huomaa, että sisältödata.jsonovatjäykistetty JSON. Siksi, kun luet sisältöädata.json, ainajäsentää se JSON-muodossaennen tietojen uudelleenkäyttöä.

Tallenna ja sulje tiedosto.

Olet nyt rakentanut verkkokaappaussovelluksen, joka kaapii kirjoja useista luokista ja tallentaa sitten kopioidut tiedot JSON-tiedostoon. Sovelluksesi monimutkaisuuden kasvaessa saatat haluta tallentaa nämä kerätyt tiedot tietokantaan tai palvella niitä API:n kautta. Se, miten tätä dataa käytetään, on todella sinun päätettävissäsi.

Johtopäätös

Tässä opetusohjelmassa rakensit indeksointirobotin, joka kaavi dataa useilta sivuilta rekursiivisesti ja tallensi sen sitten JSON-tiedostoon. Lyhyesti sanottuna opit uuden tavan automatisoida tietojen kerääminen verkkosivustoilta.

Puppeteerilla on melko paljon ominaisuuksia, jotka eivät kuuluneet tämän opetusohjelman piiriin. Katso lisätietojaPuppeteerin käyttö päättömän Chromen helppoon hallintaan. Voit myös käydäNukketeatterin virallinen dokumentaatio.

References

Top Articles
Latest Posts
Article information

Author: Sen. Ignacio Ratke

Last Updated: 07/05/2023

Views: 6548

Rating: 4.6 / 5 (76 voted)

Reviews: 91% of readers found this page helpful

Author information

Name: Sen. Ignacio Ratke

Birthday: 1999-05-27

Address: Apt. 171 8116 Bailey Via, Roberthaven, GA 58289

Phone: +2585395768220

Job: Lead Liaison

Hobby: Lockpicking, LARPing, Lego building, Lapidary, Macrame, Book restoration, Bodybuilding

Introduction: My name is Sen. Ignacio Ratke, I am a adventurous, zealous, outstanding, agreeable, precious, excited, gifted person who loves writing and wants to share my knowledge and understanding with you.