torstai 6. maaliskuuta 2014

Python hoitaa, eli kuinka Plus-deski kokeili screen scrapingia

Kun keskustelu Keva-johtaja Merja Ailuksen työsuhde-eduista oli jatkunut jo jonkin aikaa, Yle:n toimittaja Jarno Liski alkoi pyöritellä mielessään kysymyksiä: kuinka kannattava työsuhdeasunnossa asuminen on, kuka siitä todella hyötyy ja millä tavalla työsuhdeasuminen otetaan verotuksessa huomioon. Hänen lähtöoletuksensa oli, että työsuhdeasuntojen verotusarvo vastaisi huonosti asunnoista vapailla markkinoilla maksettavaa vuokraa.

Liski otti yhteyttä Plus-deskin tuottaja Juho Salmiseen, joka lähti yhdessä Teemo Tebestin kanssa viemään asiaa eteenpäin. Lopputulos on nähtävissä täällä.

Verottajan väite syyniin

Verottajan mukaan asuntojen verotusarvo vastaa keskimäärin 90-prosenttisesti asunnosta pyydettyä vuokraa. Esimerkiksi 700 eurolla vuokrattavan asunnon verotusarvon pitäisi olla noin 630 euroa. Tämä tuntui kuitenkin pitävän huonosti paikkansa. Ideana olikin tutkia, minkä suuruisia verotusarvoja asunnot todellisuudessa saavat ja kuinka hyvin verotusarvo vastaa asunnoista pyydettävää vuokraa.

Verottaja määrittelee työsuhdeasunnoille laskukaavan, jonka avulla verotusarvo määritellään asuntokohtaisesti. Verotusarvon laskennassa vaikuttavat asunnon sijainti (pääkaupunkiseutu/muu maa), pinta-ala sekä valmistumisvuosi. Työntekijä saa asuntoedusta lisähyötyä silloin, kun verotusarvo on todellista markkina-arvoa selkeästi alhaisempi, koska tällöin hänen verotuksensa on keveämpi kuin sen tulisi olla.

Teemo ja Juho pohtivat, miten asiaan pääsisi käsiksi. Verottajan kaavan pitäisi tuottaa arvo, joka on hyvin lähellä markkinahintaa. Jarno Liskin idea oli kerätä suuri määrä olemassa olevien vuokra-asuntojen tietoja ja laskea asunnoille verottajan kaavan avulla verotusarvo.

Suomessa on muutama suuri vuokra-asuntoja listaava verkkopalvelu, joiden dataa olisi mahdollista käyttää verottajan kaavan testaamiseen. Käsityönä verotusarvon ja markkina-arvon kattava vertailu ei kuitenkaan onnistuisi, sillä vuokra-asuntoja on sivustoilla tuhansia.

Oli siis kirjoitettava koodinpätkä, jonka avulla pystyttäisiin keräämään tietyn verkkopalvelun vuokra-asuntoja koskeva data, laskea niiden perusteella asunnoille verotusarvo ja analysoida saatuja arvoja. Datan keräämiseen käytettävää menetelmää kutsutaan ruudunraavinnaksi (engl. screen scraping, tuttavallisesti screippaus). Asuntojen tiedot voisi poimia miltä tahansa vuokra-asuntoja listaavalta sivustolta. Teemo käytti tässä tapauksessa Alma Median ylläpitämän Vuokraovi.com-palvelun tietoja.

Koodi ja tietokanta valmiiksi

Ruudunraapijan kirjoittamiseen Teemo päätti käyttää Python-kieltä. Screipatessa kirjoitettu koodi käy järjestelmällisesti läpi verkossa olevia nettisivuja, poimii sivulta halutut elementit ja siirtää ne tietokantaan. Tietokannaksi Teemo valitsi ennestään tutun MongoDB:n. MongoDB sopi käyttötarkoitukseen hyvin, koska noSQL-tietokannassa datalle ei tarvitse määrittää tarkkaa rakennetta etukäteen, vaan sitä voidaan täydentää ja muokata tarpeen mukaan.

Kun Teemo laittoi homman aluilleen 29. marraskuuta, Vuokraovi-palvelussa oli tarjolla noin 6 000 vuokra-asuntoa eri puolilta Suomea. Yhdelle hakutulossivulle saa näkyviin kerrallaan 10–30 vaihtoehtoa, joten tarvittavien kyselyjen määrän minimoimiseksi Teemo sääti määrän maksimiinsa. Näin screipattavaksi jäi hieman yli 200 erillistä sivua, jolla jokaisella oli 30 asuntoa. (Kuva 1)

Helmikuussa 2014 Vuokraovi-palvelussa oli tarjolla n. 8 100 vuokra-asuntoa. (Kuva 1)
Datan keräämistä mutkisti se, että kaikki tarvittavat tiedot eivät löytyneet tältä hakutulossivulta. Koodin tuli käydä läpi myös jokaisen asunnon oma sivu, sillä asunnon rakennusvuotta ei mainita kaikkien asuntojen listauksessa. Kyselyjä piti siis lopulta tehdä 200 hakutulossivuille ja 6 000 yksittäisten asuntojen omille sivuille.

Teemon ensimmäinen ajatus oli kokeilla ScraperWiki -palvelua, jota hän oli kuullut käytettävän screippaukseen. Palvelu on ollut etenkin toimittajien suosiossa ja Teemo ajatteli, että palvelun testaamisen jälkeen hän voisi opettaa sen käyttöä muille toimittajille.

ScraperWiki mahdollistaa esimerkiksi Python-koodin kirjoittamisen ilman erillisten ohjelmointiympäristöjen asentamista. Siksi palvelu sopii esimerkiksi journalisteille, joilla ei usein ole mahdollisuutta tai taitoa asentaa kaikki tarvittavia ohjelmistoja. Teemo päätyi kuitenkin tekemään toteutuksen omalla koneella omassa ympäristössä, koska tämä oli lopulta hänelle kätevämpää.

Scraper käy läpi HTML-koodia ja tallentaa määritellyt osiot talteen myöhempää käyttöä varten. (Kuva 2)
HTML-merkkauksen siivouksessa ja käsittelyssä Teemo käytti hyväkseen BeautifulSoup-nimistä Python-kirjastoa. BeautifulSoup on kirjasto, jonka avulla verkkosivuilla käytetty HTML-merkkaus voidaan muuttaa koneelle ymmärrettävään muotoon. Lopulta koodi ryömi Vuokraovi.comin sivuja muutaman tunnin ajan. Ajo tehtiin vielä uudelleen lopullista uutista varten 2. joulukuuta.>

Trouble shooting vei aikaa

Kun Teemo testasi koodia ensimmäisiä kertoja, koodi ei hakenut dataa halutulla tavalla. Vian etsintään menikin hetki. Lopulta Teemo tajusi tutkiessaan HTTP-pyyntöä, että Vuokraovi.com -sivusto asetti Internet-selaimessa tukun evästeitä, eli cookieita, joiden puute esti scraperin toiminnan. Hän päätteli, että asian korjaamiseksi samaiset evästeet tulisi asettaa myös tietokoneohjelman tekemään HTTP-pyyntöön. Tällöin HTTP-pyyntö vaikuttaisi Vuokraovi.comin näkökulmasta täysin samanlaiselta kuin jos sen tekisi esimerkiksi Google Chrome -selaimella. (Kuva 3)

HTTP-pyyntöihin liittyvät evästeet näkee Google Chrome -selaimessa Inspect Element -valikon takaa. (Kuva3)
Joskus screipatessa voi käydä niin, että jos pyyntöjä tehdään suuri määrä, palvelin voi tulkita ne vihamielisiksi ja estää ne. Vuokraoven tapauksessa reilut 6 000 pyyntöä hukkui luultavasti normaalin verkkoliikenteen sekaan. Screippausta suunnitellessa kannattaa kuitenkin miettiä, voiko rajoituksista tulla ongelmia. Esimerkiksi hakukoneyhtiö Google tunnistaa tehokkaasti koneellisesti tehtävät haut ja estää ne, koska koneellisesti tehtävät haut ovat osa heidän maksullista palveluaan.

Toteutus on ladattavissa avoimena lähdekoodina (CC-BY-SA 4.0) Ylen Github-sivulta.

Yhden päivän työ

Ennen julkaisua aineistosta siivottiin pois sellaiset kohteet, joista puuttui jokin tarvituista tiedoista, kuten rakennusvuosi, sekä autotallit ja kalustetut asunnot. Näin aineistosta saatiin vertailukelpoista. Karsimisen jälkeen pohja-aineistoksi jäi noin 5 000 vuokra-asunnon tiedot. MongoDB:stä data tulostettiin .csv-muodossa ja vietiin Googlen Spreadsheets-taulukkolaskentaohjelmaan, jossa lopullinen verotusarvolaskenta tehtiin. Aineisto on ladattavissa Ylen sivuilta Excel-muodossa.

Jutun teknisten osien toteuttaminen järjesteltävine taulukoineen kesti noin työpäivän verran, joskin homma olisi sujunut nopeammin, jos eväste-ongelman selvittämiseen ei olisi mennyt aikaa. Jatkossa vastaavanlaisia toteutuksia tehtäessä evästeet osataan ottaa paremmin huomioon.

Eräs aineistosta tehty havainto oli, että erot markkinavuokrassa suhteessa verotusarvoon olivat alueellisia. Niinpä juttu sai otsikon: Asuntoedusta hyötyy eniten Helsingissä ja kehyskunnissa – katso oman kuntasi tilanne. Jutun yhteydessä käyttäjä sai tutkia asuntojen markkinavuokran ja verotusarvon eroa sekä kunnan että postinumeroalueen perusteella.

Aineisto myös paljasti, että verotusarvon ja markkina-arvon välinen vastaavuus oli keskimäärin 73 prosenttia, siis huomattavasti verottajan edustajan ilmoittamaa 90 prosenttia pienempi.

Juttu ei ollut varsinainen yleisömenestys. Asuntoedusta nauttii Suomessa alle 20 000 henkilöä, joten kohdeyleisökään ei ollut järin suuri. Vaikuttavuutta ei voida kuitenkaan mitata pelkästään lukijamäärän perusteella.

Screippaus-kokeiluna juttu oli Plus-deskille uusi aluevaltaus ja on hyvin todennäköistä, että tulevaisuudessa tällaisia omaan datan hankintaan perustuvia "skuuppeja" tulee enemmän.

Laita siis Python töihin!

Heidi Kähkönen
Kirjoittaja on vapaa toimittaja ja datajournalismikouluttaja
Twitter:  @heidikahkonen