SEO ja Python-screippailun perusteet

Lukuaika min

Viime aikoina Pythonin käyttö ja hype on kasvanut SEO-piireissä. Python on koodikielenä kohtalaisen yksinkertainen, laskutehoiltaan voimakas sekä taipuu eri käyttötarkotuksiin. Tämä on puolestaan ajanut hyvin sen asiaa eteenpäin. Pythonilla voi esimerkiksi:

  • Kerätä tietoja verkkosivuilta tai tietokannoista
  • Analysoida ja visualisoida dataa
  • Luoda koneoppimismalleja
  • Luoda erilaisia SEO-scriptejä

Tässä artikkelissa kuitenkin keskitymme nimenomaan tietojen koneelliseen keräämiseen (eli scraping) verkkosivuilta. Tietojen kerääminen verkkosivuilta voi tulla hyödylliseksi esimerkiksi, jos haluat vertailla oman verkkokaupan tuotteiden hintoja kilpailijan hintoihin tai tutkia varastosaatavuuksia. Tässä tilanteessa voit luoda skriptin, joka käy hakemassa päivittäin kilpailijan verkkokaupan tuotteet ja hinnat sekä lisää nämä tiedot tietokantaan. Ongelma ratkaistu.

Alla olevaan artikkeliin vaaditaan hieman perustaitoja syvällisempää tietoa tietokoneen käytöstä sekä HTML:stä. Artikkelissa prosessista on käytetty termiä “screipata”.

Alla oleva artikkeli on irrotettu OIKIOn sisäisestä knowledgebasesta, jonne kootaan ja luodaan eri osaamisalueisiin liittyviä, oikiolaisten tekemiä ohjeita ja oppaita. Knowledgebasen ajatuksena on jakaa yksittäisten OIKIOn asiantuntijoiden ammattitaitoja muiden oikiolaisten kesken. Knowledgebasesta löytyy myös runsaasti erilaisia templaatteja ja automaatioita, joiden kautta voidaan säästää aikaa ja keskittyä olennaiseen, eli arvon tuottamiseen asiakkaalle turhan excel-jumpan sijasta!

Screippaaminen Pythonilla ja BeautifulSoup-kirjastolla

Alla lyhyt ja ytimekäs opas screippaamiseen Pythonilla. Tarvitset seuraavat asiat:

  • tietokone
  • internet
  • Anaconda
  • Jupyter notebooks (löytyy anacondasta)

Aloitetaan

Tietokoneen terminaaliin pitää kirjoittaa seuraavat asiat, jotta tarpeelliset kirjastot asentuvat:

pip install beautifulsoup4
pip install requests
pip install fake-useragent

Seuraavaksi avataan Anacondasta Jupiter Notebook ja uusi Python 3 -tiedosto.

Uuden tiedoston ensimmäiseen laatikkoon tuodaan nämä kirjastot:

from bs4 import BeautifulSoup
import requests
from fake_useragent import UserAgent

scrapeilua
Aloituskoodit

Tämän jälkeen pitää valita, mitä URLia lähdetään screippailemaan.

Tässä esimerkissä käytetään Tutustu asiantuntijatiimiimme -sivun URLia ja koitetaan screipata kaikkien oikiolaisten nimet ja tittelit.

Avataan yhteys ja haetaan lähdekoodi

Käytetään screippailussa feikki-useragentteja, jotta sivustot eivät tunnista meitä botiksi ja estä pääsyä sivulle. Valmistellaan se ensin:
ua = UserAgent()
header = {'user-agent':ua.chrome}

Sitten luodaan muuttuja URLille, jota halutaan screipata:
url = 'https://oikio.fi/asiantuntijatiimi/'

Avataan yhteys URLiin (tässä käytetään sitä feikki-useragenttia):
page = requests.get(url,headers=header)

Prosessin alun koodit näyttävät tältä

Käytetään BeautifulSouppia (BS), jolla voidaan jäsennellä html:ää paremmin ja tallennetaan se ’soup’-muuttujaan:
soup = BeautifulSoup(page.content, 'html.parser')

Nyt siis voimme viitata sivun lähdekoodiin pelkästään ’soup’illa.

Etsitään halutut elementit lähdekoodista

BeautifulSoupin avulla voidaan siis etsiä mitä tahansa elementtejä sivuston html:stä.
Yksinkertaisimmillaan se toimii niin, että laitetaan pisteen perään haluttu elementti, niin BS palauttaa ensimmäisen html:stä löydetyn elementin. Tämä toimii hyvin esim titlelle.
Jos halutaan löytää sivun title, se saadaan haettua kirjoittamalla Anacondaan ja ajamalla rivin:
soup.title

Mikä palauttaa:
<title>Tutustu asiantuntijatiimiimme » OIKIO</title>

Jos halutaan ainostaan elementin teksti ilman <title>-tageja, saadaan se laittamalla .text perään:
soup.title.text

Find_all -funktio

Yksi käytetyimmistä ja hyödyllisimmistä funktioista BeautifulSoupin kirjastosta, jolla voi etsiä mitä tahansa sivulta, on find_all -funktio.

Kyseinen funktio etsii annettujen parametrien avulla kaikki kriteerit täyttävät elementit ja palauttaa ne listana.

Esimerkiksi jos halutaan kaikki lista-itemit sivulta, saadaan ne näin:
all_li = soup.find_all('li')

Jos halutaan tarkentaa hakua, esimerkiksi screippaamalla vain tietyn classin tai id:n omaavat lista-itemit, voidaan se tehdä näin:
all_li = soup.find_all('li', class_ = 'haluttu-class')
all_li = soup.find_all('li', id_ = 'haluttu-id')

Aloitetaan oikiolaisten screippaus

Kun tutkitaan Chromen developer-toolseista mitä sivu on syönyt huomataan, että kaikki henkilökortit ovat divin sisällä, jonka class on single-person (näkyy heikosti kuvakaappauksessa):

Iloiset oikiolaiset!

Käydään hakemassa kaikki nämä divit muuttujaan henkilo_div:
henkilo_div = soup.find_all('div', class_ = 'single-person')

henkilo_div:ssä on nyt lista kaikista henkilökorteista. Jos katsotaan ensimmäistä:
henkilo_div[0] //ensimmäinen lista-itemi

Saadaan elementin HTML-koodi:
<div class="col-xs-12 col-md-6 col-lg-4 single-person">
<a href="https://oikio.fi/asiantuntijatiimi/taru-paavola/">
<div class="image">
<img src="/wp-content/uploads/2019/11/taru_pieni.jpg"/>
</div>
<span class="name">Taru Paavola</span>
<span class="title">Paid Social &amp; Programmatic Consultant</span>
</a>
</div>

Huomataan, että ensimmäisessä spanissa on nimi, toisessa titteli. Nämä saadaan esimerkiksi käyttämällä uusiksi find_all -funktiota, mutta tällä kertaa etsitään spaneja henkilo_div:stä.

Sillä divejä(työntekijöitä) on useita, joudutaan looppaamaan kaikkien niiden yli for-loopin avulla:

Lähdetään siis käymään henkilo_div -listaa läpi, haetaan spanit, määritellään nimi ja titteli sekä printataan ulos ”nimi: titteli”
for henkilo in henkilo_div:
spanit = henkilo.find_all('span') //etsitään spanit
nimi = spanit[0].text //ensimmäinen spani oli nimi, otetaan sen teksti
titteli = spanit[1].text //toka spani oli titteli
print(nimi, ": ", titteli) //printataan

Lopputulos näyttää tältä.

Ja lopputulos pitäisi olla jotain tämän näköistä:

Jes! Saatiin haluttu lopputulos! Koko lähdekoodi löytyy OIKIOn julkisesta Github-repositorystä.

Hyvää screippailua 🙂