Statistiline andmeteadus ja visualiseerimine MTMS.01.100     Praktikumid     Projektid     Huvitavat materjali

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.

Soovides teada saada Suur-Britannia kriminaalse tegevuse statistikat, saame seda küsida UK politsei veebiliidese kaudu. Veebiaardessile https://data.police.uk/api/crimes-street/burglary? sisestada aasta-kuu, laius- ja pikkuskraadid ja saame kätte selle koha statistika varastamise kohta esitatud teatised. Vastavad

library(tidyverse)
library(httr)
library(jsonlite)
path <- "https://data.police.uk/api/crimes-street/burglary?"

paring <- GET(url = path, 
               query = list(
                 lat = 53.421813,
                 lng = -2.330251,
                 date = "2018-05")
               )
vastus <- content(paring, as = "text", encoding = "UTF-8")

Tulemuseks on JSON fail (objekt vastus), millest tükikene on näidatud järgnevalt (R-is see tekst muidugi nii ilus välja ei näe!):

[{...
  
  # osa teksti on eemaldatud
  
  },
 {
        "category": "burglary",
        "location_type": "Force",
        "location": {
            "latitude": "53.427603",
            "street": {
                "id": 718271,
                "name": "On or near Priory Road"
            },
            "longitude": "-2.308988"
        },
        "context": "",
        "outcome_status": {
            "category": "Unable to prosecute suspect",
            "date": "2018-06"
        },
        "persistent_id": "97a11bad36eb26b43ecc5b9836cebc08c096215fc82ebd9defdc9840854f0e0d",
        "id": 64896273,
        "location_subtype": "",
        "month": "2018-05"
    }, 
  
  # osa teksti on eemaldatud
]

JSON failist omakorda info kättesaamine käib järgnevalt:

andmed <- fromJSON(vastus, flatten = TRUE) %>% 
  data.frame()

kable(head(select(andmed, month, location.street.name, outcome_status.category)))
month location.street.name outcome_status.category
2018-05 On or near Priory Road Unable to prosecute suspect
2018-05 On or near Beaufort Avenue Investigation complete; no suspect identified
2018-05 On or near Trinity Avenue Investigation complete; no suspect identified
2018-05 On or near Hyde Grove Investigation complete; no suspect identified
2018-05 On or near Fownhope Avenue Investigation complete; no suspect identified
2018-05 On or near Hollins Grove Investigation complete; no suspect identified
  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

alt text

alt text

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.