Python Panoráma 7: Webscraping a gyakorlatban9 perc olvasás

Ma már szinte minden adat, információ fellelhető az interneten. Ez az elképesztően nagy adattömeg, amely a számtalan mennyiségű weboldalon megjelenik egy különös lehetőséget rejt azok számára, akik szeretnék továbbfejleszteni Python tudásukat és megismerni egy újabb érdekes felhasználási területet.

CÉL

Ebben a részben a webscraping lesz a téma és azzal fogunk foglalatoskodni, hogy hogyan is lehet egy weboldal tartalmát felhasználható formába önteni. Úgy gondolom, hogy érdemes egy igen gyakorlatias példával belelendülni ebbe a témakörbe, mert igazából a legtöbb weboldal esetén más és más problémákba ütközik az ember, így nem érdemes annyira nagy általánosságban vizsgálódni. A webscraping-nek nagyon sok felhasználása lehetséges. Mi most egy ingatlanértékesítő weboldalból fogunk adatokat kinyerni. Célunk tehát az, hogy a weboldalon található adatokból kiszűrjük azokat, amelyek számunkra szükségesek és azokat egy cvs fájlba elmentsük úgy, hogy azok később egy elemzés alapját tudják képezni.
Köszönet Ardit Sulce-nak, akinek a kurzusa alapján készült ez a Python Panoráma rész is.

MEGVALÓSÍTÁS

A Python egy igen jól alkalmazható eszköz a webscraping területén, de természetesen mellette szükségünk van azért valamilyen szintű HTML ismeretre is. Ebben a részben szeretném, ha megismerkednénk egyben a Jupyter Notebookok használatával is. A Jupyter Notebook egy olyan szerver-kliens alkalmazás, amely segítségével a böngészőnkön keresztül írhatunk és hajthatunk végre python scripteket vagy azok egy részletét is akár.

Egy Notebook használata nagyon előnyös tud lenni, ugyanis segítségével képesek vagyunk könnyedebben szerkeszteni kódunkat, hiszen szerkesztés közben is le tudjuk azt futtatni. Ebből adódóan a Jupyter Notebook egy egyfajta átmenetet jelent egy egyszerű szöveges dokumentum és egy konzol között. A Jupyter Notebook-ot a “pip install jupyter” paranccsal tudjuk telepíteni és ha azt egy adott könyvtárban elindítjuk a Command Line segítségével, akkor ott fogja létrehozni az új Notebook-ot. A Jupyter használatával itt ismerkedhetsz meg jobban.

previous arrow
next arrow
Slider

Most, hogy tisztáztuk mi is az a Jupyter Notebook és mire jó térjünk is át a webscraping-re. Ahhoz, hogy hatékony tudjunk webscraping alkalmazásokat írni szükségünk van egy ehhez nélkülözhetetlen python könyvtárra, a BeautifulSoup-ra. Ebből adódóan első dolgunk, hogy telepítjük azt a “pip install bs4” parancs segítségével. Ez azért fontos, mert a BeautifulSoup fogja helyettünk elvégezni azokat a keresési folyamatokat, amelyeknek köszönhetően a kívánt adatokhoz hozzájuthatunk akár nagyon nagy mennyiség esetén is. A nagy mennyiség alatt arra gondolok, hogy lehet, hogy alkalmazásunknak akár több száz vagy ezer elemből kell kinyerni a megfelelő adatokat.

Következő lépésként látogassunk el a megcélzott weboldalra , amelyről adatokat szeretnénk begyűjteni. A weboldal egy ingatlanértékesítő oldal, amelyen ha rákeresünk valamilyen városra, akkor kiadja az ottani eladó lakások listáját.

previous arrow
next arrow
Slider

 

Ha megnézzük a weboldalt, akkor láthatjuk, hogy milyen jól elkülöníthető részekből áll. Van fejléce, menüje, keresősávja a weboldalnak és az eladó házak is egy-egy blokkba vannak rendezve listaként. Ahhoz, hogy ezek struktúráját jobban megérthessük, nyissuk meg az oldal forráskódját a jobb klikk “elem vizsgálata” opció kiválasztásával. Ekkor részletesen láthatjuk, hogy a weboldalnak összetevői hogyan épülnek egymásra. Keressük meg azt a div-et, amely tartalmazza a házakra vonatkozó adatokat. Ez a div a “property-card-primary-info” nevű class-hoz tartozó div lesz. Ebben a számunkra fontos összes adat megtalálható, így ezt fogjuk alapvetően felhasználni scriptünkben.

Ahhoz, hogy adatokat tudjunk kinyerni egy weboldalból meg kell adnunk a BeautifulSoup-nak, hogy milyen URL címről kérje le az oldal tartalmát, majd pedig azt is meg kell adnunk neki, hogy azt HTML forráskódként értelmezze. Amint ezekkel megvagyunk, akkor már képesek vagyunk a BeautifulSoup-on keresztül elemeket keresni a weboldalon.

Az előbb megtaláltuk melyik az a div, amely tartalmazza a szükséges adatokat. Most keressük is ki az ilyen div-eket a forráskódban a “find_all” segítségével. Ennek eredménye egy olyan lista lesz, amelynek elemei az egyes forráskód részletek. Nevezzük ezt el “all”-nak.

Most, hogy megvannak a szükséges div-ek, nézzük meg, hogyan is tudunk adatot kinyerni mondjuk az első eladó ház, mint találat, blokkjából. Először is térjünk vissza a weboldalhoz és az előbbi módszerhez hasonlóan keressük ki a ház árát tartalmazó html elemet és annak class nevét. Ezután keressünk rá az első “div”-ben, de most csak simán a “find” method-el (a find egy elemet, míg a find_all egy listát ad vissza).

Annak érdekében, hogy eredményünk ne egy html kód legyen, hanem egyszerű szöveg, a “.text” method-öt használhatjuk. Továbbá az adattábla elkészítése során csak kellemetlenségeket jelentő felesleges karaktereket és formaiságokat is eltüntethetjük a “.replace” method segítségével. Ha mindent jól csináltunk, akkor az első ház árát kell megadnia a programunknak.

import requests
from bs4 import BeautifulSoup

r=requests.get("https://www.century21.com/real-estate/rock-springs-wy/LCWYROCKSPRINGS/")
c=r.content

soup=BeautifulSoup(c,"html.parser")

all=soup.find_all("div",{"class":"property-card-primary-info"})

all[0].find("a",{"class":"listing-price"}).text.replace("\n","").replace(" ","")

Ha ezt az adatot a többi házhoz is megszeretnénk kapni, akkor nincs más dolgunk, minthogy az utolsó sort egy for loop-ba ültetjük át. Valamint, ha az adott házhoz tartozó adatokból többre is szükségünk van, akkor ugyanazt a folyamatot kell végigjárnunk, mint az eladási ár esetében. Azonban figyelnünk kell, mert lehetnek olyan paraméterek, amelyek nem minden ház esetében adottak, ilyenkor kezelnünk kell azt a helyzetet is, hogy ha a BeautifulSoup nem talál semmit az adott blokkban, akkor azt nem fogjuk tudni szöveggé alakítani. Ezt a problémát egy try except párral tudjuk feloldani.

Miután ezzel is végeztünk el kell gondolkodnunk azon, hogy hogyan fogjuk ezeket az adatokat egy pandas DataFrame-be áthelyezni. Ezt többféleképpen is meg lehet oldani. Az egyik járható út, ha egy python szótárakat tartalmazó listát hozunk létre, majd azt egyszerűen beletesszük egy DataFrame-be. Egy másik lehetséges megoldás ha az egyes paramétereket (ár, szobák, négyzetméter stb.) egy-egy üres listaként létrehozzuk, amelyet az iteráció során folyamatosan kibővítünk az “.append”-el. Később pedig ezeket a listákat töltjük be oszlopokként a DataFrame-be. Én a második utat választottam, de természetesen az első is ugyanarra az eredményre vezet. Ha végül sikerült feltöltenünk adatokkal a DataFrame-ünket, akkor pedig már csak annyi dolgunk van, hogy azt elmentjük egy “.cvs” fájlként.

Az adattáblát eredményező python scriptünknek valahogy így kell kinéznie:

import requests
import pandas as pd
from bs4 import BeautifulSoup

r=requests.get("https://www.century21.com/real-estate/rock-springs-wy/LCWYROCKSPRINGS/")
c=r.content
#c

soup=BeautifulSoup(c,"html.parser")
#print(soup.prettify())

all=soup.find_all("div",{"class":"property-card-primary-info"})

price=[]
address=[]
city=[]
beds=[]
f_bath=[]
h_bath=[]
sqr=[]

for item in all:
    p=item.find("a", {"class":"listing-price"}).text.replace("\n","").replace(" ","")
    price.append(p)
    a=item.find("div",{"class":"property-address"}).text.replace("\n","").replace("  ","")
    a=a[1:]
    address.append(a)
    c=item.find("div",{"class":"property-city"}).text.replace("\n","").replace("  ","")
    city.append(c)
    try:
        b=item.find("div",{"class":"property-beds"}).find("strong").text
        
    except:
        b=None
    beds.append(b)
    try:
        f=item.find("div",{"class":"property-baths"}).find("strong").text
    
    except:
        f=None
    f_bath.append(f)
    try:
        h=item.find("div",{"class":"property-half-baths"}).find("strong").text
        
    except:
        h=None
    h_bath.append(h)
    try:
        s=item.find("div",{"class":"property-sqft"}).find("strong").text
        
    except:
        s=None
    sqr.append(s)


df=pd.DataFrame({"Price":price, "Address":address, "City":city, "Beds":beds, "Full baths":f_bath, "Half baths":h_bath, "Squarefoot":sqr}, columns=["Price","Address","City","Beds","Full baths","Half baths","Squarefoot"])

df.to_csv("Output.csv")

TOVÁBBFEJLESZTÉS ÉS ÜZLETI FELHASZNÁLÁS

Ebben a részben a továbbfejlesztés lehetősége sajnos csekélyebb, azonban azért itt is opció lehet néhány folyamat automatizációja. Például érdemes lenne beépíteni egy olyan funkciót, amellyel programunk automatikusan a többi oldalon elhelyezkedő találatokból is adatokat tudna kinyerni.

Ami viszont ennél érdekesebb, az az üzleti felhasználása egy ilyen alkalmazásnak. Mivel az interneten szinte bármivel kapcsolatos tartalom elérhető, így maga a felhasználhatóság skálája is igen széles. Ilyen webscraping alkalmazások egyik legjellemzőbb felhasználási területe egyébként az árak összehasonlítása beszerzés esetén, piaci trendek feltérképezése vagy például a versenyképességnövelés. Úgy gondolom, hogy ebben a részben egy nagyon hasznos példát vettünk át, mert a webscraping kifejezetten izgalmas lehet az ingatlanok esetében és nagy hozzáadott értéket jelenthet.
A részhez tartozó Jupyter Notebook-ot itt nézheted meg vagy letöltheted innen.

Köszönöm, hogy végigolvastad a posztomat és ha érdekesnek találtad, akkor nézz bele a sorozat többi részébe is.

Gulácsy Dominik

About Dominik Gulácsy

Sophomore at Corvinus University of Budapest studying International Business who is motivated to use relevant academic knowledge to solve problems through optimisation. Dedicated to fully support the development of new business solutions in close collaboration with team members by IoT and data science applications. Gained experience in SQL and VBA but looking forward to learning more. A keen supporter of the circular economy.

View all posts by Dominik Gulácsy →

Leave a Reply

Your email address will not be published. Required fields are marked *