Καλύτερη απόξεση ιστού στο Python με Selenium, Beautiful Soup και pandas

Διαγραφή Ιστού

Χρησιμοποιώντας τη γλώσσα προγραμματισμού Python, είναι δυνατή η «απόξεση» δεδομένων από τον Ιστό με γρήγορο και αποτελεσματικό τρόπο.

Το scraping Ιστού ορίζεται ως:

ένα εργαλείο για τη μετατροπή των μη δομημένων δεδομένων στον Ιστό σε αναγνώσιμα από μηχανή, δομημένα δεδομένα που είναι έτοιμα για ανάλυση. (πηγή)

Το web scraping είναι ένα πολύτιμο εργαλείο στο σύνολο δεξιοτήτων του επιστήμονα δεδομένων.

Τώρα, τι να ξύσω;

Δημόσια διαθέσιμα δεδομένα

Ο ιστότοπος KanView υποστηρίζει το "Transparency in Government". Αυτό είναι επίσης το σύνθημα του ιστότοπου. Ο ιστότοπος παρέχει δεδομένα μισθοδοσίας για την πολιτεία του Κάνσας. Και αυτό είναι υπέροχο!

Ωστόσο, όπως πολλοί κυβερνητικοί ιστότοποι, ενσωματώνει τα δεδομένα σε αναλυτικούς συνδέσμους και πίνακες. Αυτό συχνά απαιτεί «πλοήγηση βέλτιστης εικασίας» για να βρείτε τα συγκεκριμένα δεδομένα που αναζητάτε. Ήθελα να χρησιμοποιήσω τα δημόσια δεδομένα που παρέχονται για τα πανεπιστήμια στο Κάνσας σε ένα ερευνητικό έργο. Η αποξήλωση των δεδομένων με την Python και η αποθήκευσή τους ως JSON ήταν αυτό που έπρεπε να κάνω για να ξεκινήσω.

Οι σύνδεσμοι JavaScript αυξάνουν την πολυπλοκότητα

Το web scraping με την Python συχνά δεν απαιτεί παρά τη χρήση της μονάδας Beautiful Soup για την επίτευξη του στόχου. Το Beautiful Soup είναι μια δημοφιλής βιβλιοθήκη Python που διευκολύνει την εφαρμογή του web scraping διασχίζοντας το DOM (μοντέλο αντικειμένου εγγράφου).

Ωστόσο, ο ιστότοπος KanView χρησιμοποιεί συνδέσμους JavaScript. Επομένως, τα παραδείγματα που χρησιμοποιούν το Python και το Beautiful Soup δεν θα λειτουργήσουν χωρίς κάποιες επιπλέον προσθήκες.

Σελήνιο για τη διάσωση

Το πακέτο Selenium χρησιμοποιείται για την αυτοματοποίηση της αλληλεπίδρασης του προγράμματος περιήγησης ιστού από την Python. Με το Selenium, είναι δυνατός ο προγραμματισμός ενός σεναρίου Python για την αυτοματοποίηση ενός προγράμματος περιήγησης ιστού. Στη συνέχεια, αυτοί οι ενοχλητικοί σύνδεσμοι JavaScript δεν αποτελούν πλέον πρόβλημα.

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

Το Selenium θα ξεκινήσει μια περίοδο λειτουργίας προγράμματος περιήγησης. Για να λειτουργεί το Selenium, πρέπει να έχει πρόσβαση στο πρόγραμμα οδήγησης του προγράμματος περιήγησης. Από προεπιλογή, θα εμφανίζεται στον ίδιο κατάλογο με το σενάριο Python. Διατίθενται σύνδεσμοι για προγράμματα οδήγησης Chrome, Firefox, Edge και Safari εδώ. Το παρακάτω παράδειγμα κώδικα χρησιμοποιεί Firefox:

#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()παραπάνω λένε στο Selenium να κάνει κλικ στον σύνδεσμο JavaScript στη σελίδα. Αφού φτάσει στη σελίδα "Τίτλοι εργασίας", το Selenium παραδίδει την πηγή της σελίδας στην Beautiful Soup.

Μετάβαση σε όμορφη σούπα

Το Beautiful Soup παραμένει ο καλύτερος τρόπος για να διασχίσετε το DOM και να αποκόψετε τα δεδομένα. Αφού ορίσετε μια κενή λίστα και μια μεταβλητή μετρητή, ήρθε η ώρα να ζητήσετε από την Beautiful Soup να αρπάξει όλους τους συνδέσμους στη σελίδα που ταιριάζουν με μια κανονική έκφραση:

#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

Από το παραπάνω παράδειγμα μπορείτε να δείτε ότι το Beautiful Soup θα ανακτήσει έναν σύνδεσμο JavaScript για κάθε τίτλο εργασίας στην κρατική υπηρεσία. Τώρα στο μπλοκ κώδικα του βρόχου for / in, το Selenium θα κάνει κλικ σε κάθε σύνδεσμο JavaScript. Στη συνέχεια, το Beautiful Soup θα ανακτήσει τον πίνακα από κάθε σελίδα.

#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

pandas: Python Data Analysis Library

Το Beautiful Soup μεταδίδει τα ευρήματα στα pandas. Το Pandas χρησιμοποιεί τη read_htmlλειτουργία του για να διαβάσει τα δεδομένα πίνακα HTML σε ένα πλαίσιο δεδομένων. Το πλαίσιο δεδομένων προσαρτάται στην προηγούμενη κενή λίστα.

Προτού ολοκληρωθεί το μπλοκ κώδικα του βρόχου, το Selenium πρέπει να κάνει κλικ στο κουμπί πίσω στο πρόγραμμα περιήγησης. Αυτό είναι έτσι ώστε ο επόμενος σύνδεσμος στο βρόχο να είναι διαθέσιμος για να κάνετε κλικ στη σελίδα καταχώρησης εργασίας.

Όταν ολοκληρωθεί ο βρόχος για / σε, το Selenium έχει επισκεφτεί κάθε σύνδεσμο τίτλου εργασίας. Η Beautiful Soup ανέκτησε τον πίνακα από κάθε σελίδα. Το Pandas έχει αποθηκεύσει τα δεδομένα από κάθε πίνακα σε ένα πλαίσιο δεδομένων. Κάθε πλαίσιο δεδομένων είναι ένα στοιχείο του datalist. Τα μεμονωμένα πλαίσια δεδομένων πίνακα πρέπει τώρα να συγχωνευτούν σε ένα μεγάλο πλαίσιο δεδομένων. Στη συνέχεια, τα δεδομένα θα μετατραπούν σε μορφή JSON με 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')

Τώρα η Python δημιουργεί το αρχείο δεδομένων JSON. Είναι έτοιμο για χρήση!

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

Η αυτοματοποιημένη διαδικασία είναι γρήγορη

Η αυτοματοποιημένη διαδικασία απόξεσης ιστού που περιγράφεται παραπάνω ολοκληρώνεται γρήγορα. Το Selenium ανοίγει ένα παράθυρο προγράμματος περιήγησης που μπορείτε να δείτε να λειτουργεί. Αυτό μου επιτρέπει να σας δείξω ένα βίντεο λήψης οθόνης για το πόσο γρήγορα είναι η διαδικασία. Βλέπετε πόσο γρήγορα το σενάριο ακολουθεί έναν σύνδεσμο, αρπάζει τα δεδομένα, επιστρέφει και κάνει κλικ στον επόμενο σύνδεσμο. Η ανάκτηση των δεδομένων από εκατοντάδες συνδέσμους είναι θέμα μονοψήφιου λεπτού.

Ο πλήρης κωδικός Python

Εδώ είναι ο πλήρης κωδικός Python. Έχω συμπεριλάβει μια εισαγωγή για πίνακα. Απαιτεί μια επιπλέον γραμμή κώδικα που θα χρησιμοποιεί τον πίνακα για να εκτυπώσει τα δεδομένα στη διεπαφή της γραμμής εντολών σας:

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

συμπέρασμα

Το web scraping με Python και Beautiful Soup είναι ένα εξαιρετικό εργαλείο για να έχετε μέσα στο skillet σας. Χρησιμοποιήστε το web scraping όταν τα δεδομένα με τα οποία πρέπει να εργαστείτε είναι διαθέσιμα στο κοινό, αλλά όχι απαραίτητα βολικά διαθέσιμα. Όταν η JavaScript παρέχει ή "αποκρύπτει" περιεχόμενο, ο αυτοματισμός του προγράμματος περιήγησης με το Selenium θα ασφαλίσει τον κωδικό σας "βλέπει" αυτό που εσείς (ως χρήστης) πρέπει να δείτε. Και τέλος, όταν απομακρύνετε πίνακες γεμάτους δεδομένα, τα pandas είναι η βιβλιοθήκη ανάλυσης δεδομένων Python που θα τα χειριστεί όλα.

Αναφορά:

Το ακόλουθο άρθρο ήταν μια χρήσιμη αναφορά για αυτό το έργο:

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

Επικοινωνήστε μαζί μου ανά πάσα στιγμή στο LinkedIn ή στο Twitter. Και αν σας άρεσε αυτό το άρθρο, δώστε μερικά χειροκροτήματα. Θα το εκτιμήσω ειλικρινά.

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

Dave Gray (@yesdavidgray) | Κελάδημα

Τα τελευταία Tweets από τον Dave Gray (@yesdavidgray). Εκπαιδευτής @FHSUInformatics * Προγραμματιστής * Μουσικός * Επιχειρηματία *…

twitter.com