Statistiline andmeteadus ja visualiseerimine MTMS.01.100     Praktikumid     Projektid     Huvitavat materjali

<!DOCTYPE html>

Andmete automatiseeritud eraldamine veebist

Andmete automatiseeritud eraldamine veebist

Veebis on aina rohkem andmeid struktureerimata kujul. Näiteks ilmaennustusi, korterite hindu, geograafilist infot, sotsiaalvõrgustike andmeid, valimistulemusi, aktsiahindu või ajalehe artikleid ei ole alati saadaval csv või Exceli failina. Alati on võimalik andmeid manuaalselt kopeerida, aga see on tülikas, aeganõudev ja vigaderohke. Veebilehtedel oleva info automatiseeritud eraldamiseks on suuresti kaks võimalust:

  1. Rakendusliidesed (web API) - struktureeritud http päringud tagastavad andmed (üldjuhul) JSON või XML formaadis.

Paljud rakendusliidesed nõuvad autentimist, mille käigus tuleb vastavale saidile kasutaja registreerida. Seejärel saab kasutaja omale unikaalse võtme, mis tuleb lisada tehtavale http päringule. Üldiselt on populaarsemad rakendusliidesed hästi dokumenteeritud ning juhendit järgides saab andmed ilusti kätte. Siiski leidub ka täielikult avatud rakendusliideseid, mis autentimist ei nõua.

Erinevaid rakendusliideseid võib leida näiteks siit või siit.

Näide:

#JSON kujul andmed autentimiseta API-st

library(httr)
library(jsonlite)
library(dplyr)

path <- "http://universities.hipolabs.com/search?country=Estonia"
paring <- GET(url = path) # http päring veebilehele
vastus <- content(paring, as = "text", encoding = "UTF-8") # andmete eraldamine päringu vastusest

andmed <- fromJSON(vastus, flatten = TRUE) %>% # andmete teisendamine JSON kujult tabelisse
  data.frame()
  1. Ekraanilt kraapimine - andmete eraldamine veebilehe lähtekoodist.

Praktikumis keskendume sellele, kuidas infot eraldada lähtekoodist.

NB! Mängureeglid:

  1. Vaata, kas andmed on struktureeritud kujul olemas või on veebilehel olemas API (kui on, siis kasuta neid ja ära kraabi).
  2. Vaata ja austa veebilehe robots.txt faili (nt ut.ee/robots.txt). See määrab, milliseid kohti veebilehest lubatakse robotil protsessida.
  3. Kraabi ainult neid andmeid, mida vajad.
  4. Oota teatud aeg (näiteks 1 sekund) pärast iga uut päringut.

Veebilehtede ülesehitusest

Et tegeleda andmete kraapimisega veebist, on vaja omada ülevaadet süntaksist, millega veebilehti koostatakse. Seega tutvume HTML-i põhitõdedega. Alustame näitest:

<!DOCTYPE html>
<html>
<head>
  <title>Page Title</title>
</head>

<body>
  <h1>This is a Heading</h1>
  <p>This is a paragraph.</p>
</body>

</html>

Et näha tulemust, võid ülevaloleva koodi salvestada .html failina ning avada brauseris. Alternatiivina kliki siia.

Lühidalt kokku võttes: HTML koosneb siltidest (tags), mis märgitakse sümbolite < > vahele ning mille abil kirjeldatakse veebilehe struktuuri.

Rohkem infot HTML siltide kohta leiad siit.

HTML määrab veebilehe üldise struktuuri. Et muuta teksti värvi ja muud stiili, selleks kasutatakse CSS-i.

Vaata näiteid:

Andmete kättesaamise idee seisnebki selles, et veebilehe lähtekoodist leiame ülesse vajaliku sildi ning eraldame vastava väärtuse. CSS-i määratud klassid ja id-d, aitavad meil tihti hõlpsamini vajaliku info asukohta määrata.

Rohkem infot HTMLi ja CSS kohta leiad:

CSS-i õppimiseks on tore tutorial:

Paketi rvest minimaalne näide

rvest on Hadley tehtud pakett veebilehtedelt andmete kraapimiseks.

HTML

Minimaalne näide, kuidas eelneval pildil näidatud HTML lähtekoodist eraldada pealkirja ja lõiku.

library(rvest)

html_source = '
<!DOCTYPE html>
<html>
<head>
  <title>Page Title</title>
</head>

<body>
  <h1>This is a Heading</h1>
  <p>This is a paragraph.</p>
</body>

</html>
'

page = read_html(html_source)

# pealkirja eraldamine
page %>% 
  html_node("h1") %>%
  html_text()
## [1] "This is a Heading"
# lõigu eraldamine
page %>% 
  html_node("p") %>%
  html_text()
## [1] "This is a paragraph."

Funktsioonile read_html võib ette anda kas veebilehe urli, faili asukoha või sõne.

XML

XML on märgistuskeel, mille eesmärgiks on struktureeritud info jagamine. XML koosneb kasutaja defineeritud siltidest (tags), mis märgitakse sümbolite < > vahele ja mille abil kirjeldatakse andmete struktuuri. Järgnevalt on toodud minimalistlik näide, kuidas XML failist eraldada infot.

library(rvest)

xml_source = '
<?xml version="1.0" encoding="UTF-8"?>
<inimesed>
  <inimene>
    <nimi>Mati</nimi>
    <vanus>25</vanus>
  </inimene>
  <inimene>
    <nimi>Kati</nimi>
    <vanus>40</vanus>
  </inimene>
</inimesed>
'

page = read_html(xml_source)

# vanuste eraldamine
page %>% 
  html_nodes("inimene") %>%
  html_node("vanus") %>%
  html_text()
## [1] "25" "40"

Funktsiooni read_html asemel võib kasutada funktsiooni read_xml või html_node asemel xml_node, kuid vastavad XML-ekvivalendid kutsuvad välja vastavad html funktsioonid, seega ei ole tegelikult vahet, kumba varianti kasutada.

Uuri ka rvest dokumentatsiooni.