Jobb webes kaparás a Pythonban szelénnel, gyönyörű levessel és pandákkal

Webes kaparás

A Python programozási nyelv használatával gyorsan és hatékony módon lehet „lekaparni” az adatokat az internetről.

A webes kaparás a következő:

eszköz az interneten lévő strukturálatlan adatok gépi olvasható, strukturált adatokká alakítására, amely elemzésre kész. (forrás)

A webes kaparás értékes eszköz az adatkutató készségkészletében.

Most mit kaparjon meg?

Nyilvánosan elérhető adatok

A KanView webhelye támogatja az „Átláthatóság a kormányban” c. Ez az oldal szlogenje is. A webhely Kansas állam fizetésügyi adatait tartalmazza. És ez nagyon jó!

Mégis, mint sok kormányzati weboldal, az adatokat lefelé mutató linkekbe és táblázatokba temeti el. Ehhez gyakran a „legjobb találgatás navigációra” van szükség a kívánt adatok megtalálásához. Kutatási projektben akartam felhasználni a Kansas-i egyetemek számára biztosított nyilvános adatokat. Az adatok beolvasását a Python segítségével és JSON néven történő mentését kellett elvégeznem.

A JavaScript-linkek növelik a bonyolultságot

A Python-nal történő webes kaparás gyakran csak a Gyönyörű leves modul használatát igényli a cél eléréséhez. A Beautiful Soup egy népszerű Python könyvtár, amely megkönnyíti a webes lekérdezést a DOM (dokumentumobjektum modell) bejárásával.

A KanView webhely azonban JavaScript-hivatkozásokat használ. Ezért a Python és a Gyönyörű leves használatával kapcsolatos példák nem működnek különösebb kiegészítés nélkül.

Szelén a megmentéshez

A Selenium csomag a webböngésző Python-beli interakcióinak automatizálására szolgál. A Selenium segítségével Python szkript programozása lehetséges a webböngésző automatizálásához. Utána ezek a bosszantó JavaScript-linkek már nem jelentenek problémát.

from selenium import webdriver from selenium.webdriver.common.keys import Keys from bs4 import BeautifulSoup import re import pandas as pd import os

A Selenium most elindítja a böngésző munkamenetét. A Selenium működéséhez hozzáférnie kell a böngésző illesztőprogramjához. Alapértelmezés szerint ugyanabban a könyvtárban fog kinézni, mint a Python szkript. A Chrome, Firefox, Edge és Safari illesztőprogramok linkjei itt érhetők el. Az alábbi példakód a Firefoxot használja:

#launch url url = "//kanview.ks.gov/PayRates/PayRates_Agency.aspx" # create a new Firefox session driver = webdriver.Firefox() driver.implicitly_wait(30) driver.get(url) python_button = driver.find_element_by_id('MainContent_uxLevel1_Agencies_uxAgencyBtn_33') #FHSU python_button.click() #click fhsu link

A python_button.click()fentiek azt mondják a Seleniumnak, hogy kattintson az oldalon található JavaScript linkre. Miután megérkezett a Munka címek oldalra, a Szelén átadja az oldal forrását a Gyönyörű levesnek.

Átállás a gyönyörű levesbe

A Beautiful Soup továbbra is a legjobb módszer a DOM-on való áthaladáshoz és az adatok lekaparásához. Miután definiált egy üres listát és egy számláló változót, itt az ideje megkérni a Gyönyörű levest, hogy ragadja meg az oldalon az összes olyan hivatkozást, amely megfelel egy reguláris kifejezésnek:

#Selenium hands the page source to Beautiful Soup soup_level1=BeautifulSoup(driver.page_source, 'lxml') datalist = [] #empty list x = 0 #counter for link in soup_level1.find_all('a', id=re.compile("^MainContent_uxLevel2_JobTitles_uxJobTitleBtn_")): ##code to execute in for loop goes here

A fenti példából láthatja, hogy a Beautiful Soup lekér egy JavaScript-hivatkozást az állami hivatal minden munkaköréhez. Most a for / in ciklus kódblokkjában a Selenium az egyes JavaScript linkekre kattint. Ezután a Gyönyörű leves minden oldalról lekéri a táblázatot.

#Beautiful Soup grabs all Job Title links for link in soup_level1.find_all('a', id=re.compile("^MainContent_uxLevel2_JobTitles_uxJobTitleBtn_")): #Selenium visits each Job Title page python_button = driver.find_element_by_id('MainContent_uxLevel2_JobTitles_uxJobTitleBtn_' + str(x)) python_button.click() #click link #Selenium hands of the source of the specific job page to Beautiful Soup soup_level2=BeautifulSoup(driver.page_source, 'lxml') #Beautiful Soup grabs the HTML table on the page table = soup_level2.find_all('table')[0] #Giving the HTML table to pandas to put in a dataframe object df = pd.read_html(str(table),header=0) #Store the dataframe in a list datalist.append(df[0]) #Ask Selenium to click the back button driver.execute_script("window.history.go(-1)") #increment the counter variable before starting the loop over x += 1

pandák: Python Data Analysis Library

A gyönyörű leves átadja a megállapításokat a pandáknak. A Pandas read_htmla HTML tábla adatait adatkeretbe olvassa. Az adatkeret az előzőleg definiált üres listához kerül.

Mielőtt a ciklus kódblokkja elkészülne, a Selenium-nak a Vissza gombra kell kattintania a böngészőben. Ez azt jelenti, hogy a ciklus következő linkje elérhető lesz, hogy rákattinthasson az álláslistára.

Amikor a for / in ciklus befejeződött, a Selenium meglátogatta az összes munkakör linket. A Beautiful Soup minden oldalról lekérte a táblázatot. A Pandas az egyes táblák adatait egy adatkeretben tárolta. Minden adatkeret egy elem a datalistában. Az egyes táblák adatkereteinek most egy nagy adatkeretbe kell egyesülniük. Ezután az adatokat JSON formátumba konvertáljuk a pandas.Dataframe.to_json fájlba:

#loop has completed #end the Selenium browser session driver.quit() #combine all pandas dataframes in the list into one big dataframe result = pd.concat([pd.DataFrame(datalist[i]) for i in range(len(datalist))],ignore_index=True) #convert the pandas dataframe to JSON json_records = result.to_json(orient='records')

Most a Python létrehozza a JSON adatfájlt. Használatra kész!

#get current working directory path = os.getcwd() #open, write, and close the file f = open(path + "\\fhsu_payroll_data.json","w") #FHSU f.write(json_records) f.close()

Az automatizált folyamat gyors

A fent leírt automatizált web-kaparási folyamat gyorsan befejeződik. A Selenium megnyit egy böngészőablakot, amelyen látható, hogy működik. Ez lehetővé teszi számomra, hogy képernyőn rögzítsen videót arról, hogy milyen gyors a folyamat. Látja, hogy a szkript milyen gyorsan követi a linket, megragadja az adatokat, visszamegy és a következő linkre kattint. Több száz hivatkozás adatainak visszakeresését egyjegyű percek kérdésévé teszi.

A teljes Python kód

Itt van a teljes Python kód. Felvettem egy táblázatos importot. Ehhez egy további kódsorra van szükség, amely a táblázatok segítségével szépen kinyomtatja az adatokat a parancssori felületre:

from selenium import webdriver from selenium.webdriver.common.keys import Keys from bs4 import BeautifulSoup import re import pandas as pd from tabulate import tabulate import os #launch url url = "//kanview.ks.gov/PayRates/PayRates_Agency.aspx" # create a new Firefox session driver = webdriver.Firefox() driver.implicitly_wait(30) driver.get(url) #After opening the url above, Selenium clicks the specific agency link python_button = driver.find_element_by_id('MainContent_uxLevel1_Agencies_uxAgencyBtn_33') #FHSU python_button.click() #click fhsu link #Selenium hands the page source to Beautiful Soup soup_level1=BeautifulSoup(driver.page_source, 'lxml') datalist = [] #empty list x = 0 #counter #Beautiful Soup finds all Job Title links on the agency page and the loop begins for link in soup_level1.find_all('a', id=re.compile("^MainContent_uxLevel2_JobTitles_uxJobTitleBtn_")): #Selenium visits each Job Title page python_button = driver.find_element_by_id('MainContent_uxLevel2_JobTitles_uxJobTitleBtn_' + str(x)) python_button.click() #click link #Selenium hands of the source of the specific job page to Beautiful Soup soup_level2=BeautifulSoup(driver.page_source, 'lxml') #Beautiful Soup grabs the HTML table on the page table = soup_level2.find_all('table')[0] #Giving the HTML table to pandas to put in a dataframe object df = pd.read_html(str(table),header=0) #Store the dataframe in a list datalist.append(df[0]) #Ask Selenium to click the back button driver.execute_script("window.history.go(-1)") #increment the counter variable before starting the loop over x += 1 #end loop block #loop has completed #end the Selenium browser session driver.quit() #combine all pandas dataframes in the list into one big dataframe result = pd.concat([pd.DataFrame(datalist[i]) for i in range(len(datalist))],ignore_index=True) #convert the pandas dataframe to JSON json_records = result.to_json(orient='records') #pretty print to CLI with tabulate #converts to an ascii table print(tabulate(result, headers=["Employee Name","Job Title","Overtime Pay","Total Gross Pay"],tablefmt='psql')) #get current working directory path = os.getcwd() #open, write, and close the file f = open(path + "\\fhsu_payroll_data.json","w") #FHSU f.write(json_records) f.close()

Következtetés

Web kaparás a Python és gyönyörű leves kiváló eszköz, hogy az Ön skillset. Akkor használja a webes kaparást, ha a munkavégzéshez szükséges adatok a nyilvánosság számára elérhetők, de nem feltétlenül kényelmesen elérhetők. Amikor a JavaScript tartalmat nyújt vagy „elrejt”, a böngésző automatizálása a Seleniummal biztosítja, hogy a kódod „lássa” azt, amit neked (felhasználóként) látnod kell. És végül, amikor adatokkal teli táblákat kapar , a pandák a Python adatelemző könyvtár, amely az egészet kezeli.

Referencia:

A következő cikk hasznos referencia volt a projekthez:

//pythonprogramminglanguage.com/web-scraping-with-pandas-and-beautifulsoup/

Bármikor forduljon hozzám a LinkedIn vagy a Twitter segítségével. És ha tetszett ez a cikk, adj neki néhány tapsot. Őszintén értékelni fogom.

//www.linkedin.com/in/davidagray/

Dave Gray (@ yesdavidgray) | Twitter

A legújabb tweetek Dave Gray-től (@yesdavidgray). Oktató @FHSUInformatics * Fejlesztő * Zenész * Vállalkozó *

twitter.com