Parem veebikraapimine Pythonis koos seleeni, kauni supi ja pandadega

Veebi kraapimine

Kasutades Pythoni programmeerimiskeelt, on võimalik andmeid kiirelt ja tõhusalt veebist "kraapida".

Veebi kraapimine on määratletud järgmiselt:

tööriist veebis struktureerimata andmete muutmiseks masinloetavateks struktureeritud andmeteks, mis on analüüsiks valmis. (allikas)

Veebi kraapimine on väärtuslik vahend andmeteadlase oskuste kogumis.

Mida nüüd kraapida?

Avalikult kättesaadavad andmed

KanView veebisait toetab „Läbipaistvust valitsuses”. See on ka saidi loosung. Sait pakub Kansase osariigi palgafondi andmeid. Ja see on suurepärane!

Kuid nagu paljud valitsuse veebisaidid, matab see andmed ka üksikasjalikumatesse linkidesse ja tabelitesse. See nõuab otsitavate andmete leidmiseks sageli parimat navigeerimist. Tahtsin kasutada Kansase ülikoolide avalikke andmeid uurimisprojektis. Andmete kraapimine Pythoni abil ja salvestamine JSON-iga oli see, mida pidin alustamiseks tegema.

JavaScripti lingid suurendavad keerukust

Veebikraapimine Pythoniga nõuab eesmärgi saavutamiseks sageli muud kui mooduli Kaunis supp kasutamist. Kaunis supp on populaarne Pythoni teek, mis muudab veebikraapimise DOM-i (dokumendiobjekti mudel) läbimise abil hõlpsamini rakendatavaks.

KanView veebisait kasutab siiski JavaScripti linke. Seetõttu ei tööta Pythoni ja kauni supi kasutamise näited ilma täiendavate lisadeta.

Seleen päästmiseks

Seleeni paketti kasutatakse veebibrauseri interaktsiooni automatiseerimiseks Pythoni kaudu. Seleniumiga on võimalik veebibrauseri automatiseerimiseks programmeerida Pythoni skript. Pärast pole need tüütud JavaScripti lingid enam probleemiks.

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

Selenium alustab nüüd brauseriseanssi. Seleni töötamiseks peab see pääsema juurde brauseri draiverile. Vaikimisi näeb see välja Pythoni skriptiga samas kataloogis. Lingid Chrome'i, Firefoxi, Edge'i ja Safari draiveritele on saadaval siin. Allolev näite kood kasutab Firefoxi:

#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

python_button.click()Eespool räägib Seleen klõpsata JavaScript link lehel. Pärast ametinimetuste lehele jõudmist annab Selen leheallika välja kaunile supile.

Üleminek ilusale supile

Kaunis supp on endiselt parim viis DOM-ist läbida ja andmeid kraapida. Pärast tühja loendi ja loendurimuutuja määratlemist on aeg paluda kaunil supil haarata kõik lehel olevad lingid, mis vastavad tavaväljendile:

#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

Ülaltoodud näitest näete, et Kaunis supp otsib riigiametis iga ametinimetuse jaoks JavaScripti lingi. Nüüd tsükli for / in koodiplokis klõpsab Selenium iga JavaScripti linki. Kaunis supp otsib seejärel tabeli igalt lehelt.

#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

pandad: Pythoni andmeanalüüsi raamatukogu

Ilus supp annab leiud pandadele edasi. Pandas kasutab oma read_htmlfunktsiooni HTML-tabeli andmete lugemiseks andmekaadrisse. Andmekaader lisatakse eelnevalt määratletud tühjale loendile.

Enne tsükli koodiploki valmimist peab Selenium klõpsama brauseris nuppu Tagasi. See on nii, et tsükli järgmine link on saadaval tööloendi lehel klõpsamiseks.

Kui tsükkel for / in on lõpule jõudnud, on Selenium külastanud kõiki ametinimetuste linke. Ilus supp on tabeli igalt lehelt kätte saanud. Pandas on iga tabeli andmed salvestanud andmekaadrisse. Iga andmekaader on üks element datalistis. Individuaalsed tabeli andmeraamid peavad nüüd ühinema üheks suureks andmekaadriks. Seejärel teisendatakse andmed pandas.Dataframe.to_json abil JSON-vormingusse:

#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')

Nüüd loob Python JSON-faili. See on kasutamiseks valmis!

#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()

Automatiseeritud protsess on kiire

Eespool kirjeldatud automatiseeritud veebi kraapimisprotsess lõpeb kiiresti. Seleen avab brauseriakna, mida näete töötavat. See võimaldab mul näidata teile ekraanipildi videot selle kohta, kui kiire protsess on. Näete, kui kiiresti skript linki järgib, haarab andmed, läheb tagasi ja klõpsab järgmisel lingil. See muudab sadade linkide andmete hankimise ühekohalise minutiga.

Pythoni täielik kood

Siin on täielik Pythoni kood. Lisasin tabelite importimise. See nõuab täiendavat koodirida, mis kasutab tabelite abil andmete printimiseks teie käsurea liidesesse:

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()

Järeldus

Web kraapides koos Python ja Ilus Soup on suurepärane vahend on teie skillset. Kasutage veebikraapimist, kui töötamiseks vajalikud andmed on avalikkusele kättesaadavad, kuid mitte tingimata mugavalt kättesaadavad. Kui JavaScripti sisu pakub või peidab, tagab brauseri automaatika seleeniga teie koodi selle, et see "näeks" seda, mida teie (kasutaja) peaksite nägema. Ja lõpuks, kui kraapite tabeleid täis andmeid, on pandad Pythoni andmeanalüüsi kogu, mis seda kõike haldab.

Viide:

Järgmine artikkel oli selle projekti jaoks kasulik viide:

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

Võtke minuga ühendust LinkedInis või Twitteris. Ja kui see artikkel teile meeldis, tehke talle paar plaksutamist. Hindan seda siiralt.

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

Dave Gray (@yesdavidgray) | Twitter

Dave Gray uusimad säutsud (@yesdavidgray). Juhendaja @FHSUInformatics * Arendaja * Muusik * Ettevõtja *…

twitter.com