de Dave Gray

Web Scraping

Folosind limbajul de programare Python, este posibil să „răzuiești” datele de pe web într-un mod rapid și eficient.

Scrapingul web este definit ca:

un instrument pentru transformarea datelor nestructurate de pe web în date structurate care pot fi citite de mașini, care este gata pentru analiză. (sursă)

Răzuirea web este un lucru valoros instrument din setul de competențe al savantului.

Acum, ce să răzuiești?

Razuire web mai buna in Python cu seleniu supa frumoasa
„Opțiuni de căutare detaliate” == Faceți clic în continuare până găsiți ceea ce doriți.

Date disponibile public

KanView site-ul web acceptă „Transparența în guvern”. Acesta este și sloganul site-ului. Site-ul oferă date de salarizare pentru statul Kansas. Și asta e minunat!

Cu toate acestea, la fel ca multe site-uri web guvernamentale, îngropă datele în legături și tabele detaliate. Acest lucru necesită adesea „navigare cu cea mai bună estimare” pentru a găsi datele specifice pe care le căutați. Am vrut să folosesc datele publice furnizate pentru universitățile din Kansas într-un proiect de cercetare. Scraperul datelor cu Python și salvarea lor ca JSON a fost ceea ce trebuia să fac pentru a începe.

Răzuirea web cu Python nu necesită adesea decât utilizarea fișierului Supă frumoasă modul pentru a atinge obiectivul. Supă frumoasă este o populară bibliotecă Python care face răzuirea web prin traversarea DOM (model de obiect document) mai ușor de implementat.

Însă KanView site-ul web utilizează linkuri JavaScript. Prin urmare, exemplele care utilizează Python și Beautiful Soup nu vor funcționa fără unele adăugări suplimentare.

1611976326 307 Razuire web mai buna in Python cu seleniu supa frumoasa
https://pypi.python.org/pypi/selenium

Seleniu pentru salvare

Pachet de seleniu este folosit pentru automatizarea interacțiunii browserului web din Python. Cu Selenium, este posibilă programarea unui script Python pentru automatizarea unui browser web. Ulterior, acele linkuri JavaScript plictisitoare nu mai sunt o problemă.

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

Selenium va începe acum o sesiune de browser. Pentru ca Selenium să funcționeze, trebuie să acceseze driverul browserului. În mod implicit, va arăta în același director cu scriptul Python. Link-uri către driverele Chrome, Firefox, Edge și Safari disponibil aici. Exemplul de cod de mai jos folosește Firefox:

#launch url
url = "http://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() de mai sus îi spune Selenium să facă clic pe linkul JavaScript de pe pagină. După ce a ajuns la pagina Titluri de locuri de muncă, Selenium predă sursa paginii către Beautiful Soup.

1611976326 423 Razuire web mai buna in Python cu seleniu supa frumoasa
https://www.crummy.com/software/BeautifulSoup/

Trecerea la supă frumoasă

Supă frumoasă rămâne cel mai bun mod de a traversa DOM și de a răzuie datele. După ce ați definit o listă goală și o variabilă de contor, este timpul să cereți Beautiful Soup să ia toate linkurile de pe pagină care se potrivesc cu o expresie regulată:

#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

Din exemplul de mai sus puteți vedea că Beautiful Soup va prelua un link JavaScript pentru fiecare titlu de post la agenția de stat. Acum, în blocul de cod al buclei for / in, Selenium va face clic pe fiecare link JavaScript. Supa frumoasă va prelua apoi tabelul din fiecare pagină.

#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
1611976326 221 Razuire web mai buna in Python cu seleniu supa frumoasa
https://pandas.pydata.org/

panda: Python Data Analysis Library

Supa frumoasă transmite descoperirile pandelor. Pandas folosește read_html funcție pentru a citi datele tabelului HTML într-un cadru de date. Cadrul de date este atașat la lista goală definită anterior.

Înainte ca blocul de cod al buclei să fie complet, Selenium trebuie să facă clic pe butonul Înapoi din browser. Astfel, următorul link din buclă va fi disponibil pentru a face clic pe pagina de listare a posturilor.

Când bucla for / in s-a finalizat, Selenium a vizitat fiecare link pentru titlul postului. Beautiful Soup a recuperat tabelul din fiecare pagină. Pandas a stocat datele din fiecare tabel într-un cadru de date. Fiecare cadru de date este un element din datalist. Cadrele de date individuale ale tabelelor trebuie acum să se îmbine într-un singur cadru de date mare. Datele vor fi apoi convertite în format JSON cu pandas.Dataframe.to_json:

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

Acum Python creează fișierul de date JSON. Este gata de utilizare!

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

Procesul automat este rapid

Procesul automat de răzuire web descris mai sus se finalizează rapid. Selenium deschide o fereastră de browser pe care o puteți vedea funcționând. Acest lucru îmi permite să vă arăt un videoclip cu captură de ecran cu cât de rapid este procesul. Vedeți cât de repede scriptul urmează un link, apucă datele, se întoarce și face clic pe linkul următor. Recuperarea datelor de la sute de link-uri face ca minute dintr-o singură cifră.

Codul Python complet

Iată codul complet Python. Am inclus un import pentru tabulare. Necesită o linie de cod suplimentară care va utiliza tabulare pentru a imprima destul de bine datele pe interfața liniei de comandă:

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 = "http://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()
1611976327 2 Razuire web mai buna in Python cu seleniu supa frumoasa
Fotografie de Artem Sapegin pe Unsplash

Concluzie

Răzuire web cu Piton și Supă frumoasă este un instrument excelent pe care îl aveți în cadrul abilităților dvs. Utilizați web scraping atunci când datele cu care trebuie să lucrați sunt disponibile publicului, dar nu neapărat disponibile în mod convenabil. Când JavaScript furnizează sau „ascunde” conținut, automatizarea browserului cu Seleniu vă va asigura codul „vede” ceea ce ar trebui să vedeți dvs. (ca utilizator). Și, în sfârșit, când răzuiești tabele pline de date, panda este biblioteca Python de analiză a datelor care se va ocupa de toate.

Referinţă:

Următorul articol a fost o referință utilă pentru acest proiect:

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

Contactează-mă oricând LinkedIn sau Stare de nervozitate. Și dacă ți-a plăcut acest articol, dă-i câteva palme. Voi aprecia sincer.

https://www.linkedin.com/in/davidagray/

Dave Gray (@yesdavidgray) | Stare de nervozitate
Cele mai recente tweets de la Dave Gray (@yesdavidgray). Instructor @FHSUInformatics * Dezvoltator * Muzician * Antreprenor * …
twitter.com