Za današnje pedavanje je potrebno instaliriati SelectorGadget (Instalacija je moguća preko linka.). SelectorGadget je Chrome ekstenzija koja omogućava jednostavno pronalaženje CSS selektora na web stranicama. SelectorGadget je dostupan isključivo za Chrome. U slučaju da više volite Firefox, alternativa je ScrapeMate.
Prisjetite se da je rvest automatski instaliran sa tidyverse paketom. Ipak, ovo je prigodan način da instalirate i učitate sve prethodno pobrojane pakete ukoliko to niste već napravili:
## učitaj i instaliraj pakete
if (!require("pacman")) install.packages("pacman")
pacman::p_load(tidyverse, rvest, lubridate, janitor, hrbrthemes)
## ggplot2 tema (po želji)
theme_set(hrbrthemes::theme_ipsum())Ovo predavanje se bavi preuzimanjem sadržaja sa web-a na vaše lokalno računalo. Svi već imamo iskustvo sa pregledom web sadržaja u browser-u (Chrome, Firefox,…) pa je vjerojatno logično da sadržaj koji gledamo negdje mora postojati u podatkovnom obliku. Važno je razumjeti da postoje dva osnovna načina na koja se web sadržaj prikazuje (engl.render) u browser-u:
Ovdje pogledajte ako vas zanima više detalja (uključujući primjere).
Za potrebe ovog predavanja, glavni su sljedeći elementi:
U ovom predavanju ćemo proći kroz glavne razlike između ova dva pristupa i dati pregled implikacija koje oni imaju za preuzimanje web sadržaja. Važno je istaknuti da webscraping uključuje ponešto “detektivskog” posla. Često će biti potrebno prilagoditi korake koje ćemo objasniti na predavanju prema podatcima koje želimo preuzeti, a procedure koje funkcioniraju na jednoj stranici neće nužno funkcionirati i na drugoj (ponekad neće funkcionirati ni na istoj nakon nekog vremena!). Zbog toga se je moguće reći da webscraping podjednako uključuje umjetnost (kreativnost) i znanost (razumijevanje).
Pozitivna strana svega je da server-strana i client-strana dozvoljavaju preuzimanje web sadržaja. Kao što ćemo uskoro vidjeti, preuzimanje podataka sa web stranice koja funkcionira na client-strani (API) je često jednostavnije, pogotovo kada nam je cilj preuzeti veću (bulk) količinu podataka. Za webscraping vrijedi općenito pravilo: ako vidite podatke u browseru, možete ih i preuzeti.
Prethodna rečenica ne uzima u obzir važne etičke i zakonske aspekte preuzimanja sadržaja sa interneta. Samo zato što možete nešto preuzeti sa interneta, ne zanči da biste to i trebali učiniti. Vaša je odgovornost procijeniti da li web stranica polaže zakonska ograničenja na sadržaj koji se tamo nalazi. Alati koje ćemo koristiti u ovom predavanju su uistinu moćni, mogu prenapregnuti server i izazvati poteškoće u radu ili pad web stranice. Glavna maksima kod webscraping-a je stoga “budite pristojni”!
Glavni paket u R-u za preuzimanje web sadržaja na strani severa je rvest (link). To je jednostavan, ali moćan paket za webscraping inspiriran Python-ovom Beautiful Soup (link) platformom, ali uz dodatne tidyverse funkcionalnosti :-). rvest je osmišljen za rad sa stranicama koje su procesuirane na strani severa i zbog toga zahtijeva određeno razumijevanje CSS selektora…pa pogledajmo o čemu se radi…
Za informacije o CSS (i.e Cascading Style Sheets) i SelectorGadget-u pročitajte više na interentu. Ukratko, CSS je jezik koji određuje izgled HTML dokumenata (uključujući i web stranice) tako što omogućuje browseru skup pravila za prikaz koja se formiraju na osnovi:
Za preuzimanje podataka sa web stranice je bitno identificirati CSS selektore sadržaja koji želimo skinuti jer tako izoliramo djelove stranice od interesa. Upravo tu dolazi do izražaja korisnost SelectorGadget-a. U ovom predavanju ćemo proći kroz primjer korištenja SelectorGadget-a, no preporučljivo je pogledati vignette prije nastavka.
Stavimo sve ovo u praktični kontekst kroz preuzimanje podataka sa Wikipedia stranice Men’s 100 metres world record progression.
Prvo, otvorite ovu stranicu u vašem browser-u. Upoznajte se sa strukturom stranice: Kakve objekte stranica sadrži? Koliko ima tablica? Da li tablice imaju iste kolone? Kakvi su rasponi redova i kolona? itd.
Nakon što ste se upoznali sa strukturom stranice, učitajte cijelu stranicu u R koristeći rvest::read_html() funkciju:
# library(rvest) ## već učitano
m100 <- read_html("http://en.wikipedia.org/wiki/Men%27s_100_metres_world_record_progression")
# pogledaj objekt
m100## {html_document}
## <html class="client-nojs" lang="en" dir="ltr">
## [1] <head>\n<meta http-equiv="Content-Type" content="text/html; charset=UTF-8 ...
## [2] <body class="mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject ...
Kao što vidite, ovo je XML dokument1 koji sadrži sve potrebno za procesuiranje Wikipedia stranice. To je otprilike kao da promatrate cjeli .pdf dokument (specifikacije, formule, itd.), a želite preuzeti samo jednu tablicu ili dio poglavlja.
Pokušajmo sada izolirati prvu tablicu sa naslovom Unofficial progression before the IAAF. Kao što je objašnjeno u rvest vignette-i, možemo koristiti funkciju rvest::html_nodes() kako bismo izolirali i preuzeli ovu tablicu iz HTML dokumenta kroz specifikaciju odggovarajućih CSS selektora. Potom je potrebno pretvoriti objekt u data.frame koristeći rvest::html_table() funkciju. Preporuča se korištenje fill=TRUE argumenta u ovom slučaju, jer će se u suprotnom javiti problemi sa formatiranjem redova zbog razmaka u Wiki tablici.
Koristiti ćemo SelectorGadget za identifikaciju CSS selektora. U ovom slučaju je riječ o “div+ .wikitable :nth-child(1)” elementu. Pogledajmo kako to funkcionira:
m100 %>%
html_nodes("div+ .wikitable :nth-child(1)") %>%
html_table(fill=TRUE) ## Error in matrix(unlist(values), ncol = width, byrow = TRUE): 'data' must be of a vector type, was 'NULL'
Izgleda da nešto nije u redu…!? Dobili smo error. Bez da ulazimo u detalje, valja znati da je SelectorGadget ponekad neprecizan….iako je riječ o izvrsnom alatu koji uglavnom radi dobro. Ipak, ponekad ono što izgleda kao dobar selektor (i.e. naglašeno žuto) nije točno ono što tražimo. Ovaj error je namjerno prikazan radi skretanja pažnje na potencijalne probleme koji se mogu javiti pri korištenju SelectorGadget-a. Treba još jednom reći: Webscraping je u jednakoj mjeri umjetnost i znanost!
Na sreću, postoji i precizniji način određivanja točnog selektora, a odnosi se na korištenje “inspect web element” opcije koju ima većina modernih browser-a. U ovom slučaju koristimo (Ctrl+Shift+I, ili desni klik miša i izaberi “Inspect”). Potom ćemo proći kroz source elemente dok Chrome ne istakne tablicu koja nas zanima. Nakon toga opet desni klik miša i izaberite Copy -> Copy selector. Pogledajte opisanu proceduru: