L'HTML è quasi intuitivo Il CSS è un grande progresso che separa in modo pulito la struttura di una pagina dal suo aspetto grafico. JavaScript aggiunge qualche pizazz. Questa è la teoria. Il mondo reale è un po 'diverso.
In questo tutorial, imparerai come il contenuto che vedi nel browser viene effettivamente visualizzato e come procedere per eliminarlo quando necessario. In particolare, imparerai come contare i commenti di Disqus. I nostri strumenti saranno Python e pacchetti fantastici come le richieste, BeautifulSoup e Selenium.
Lo scraping Web è la pratica di recuperare automaticamente il contenuto di pagine Web progettate per interagire con utenti umani, analizzarle ed estrarre alcune informazioni (possibilmente navigando in collegamenti ad altre pagine). A volte è necessario se non c'è altro modo per estrarre le informazioni necessarie. Idealmente, l'applicazione fornisce un'API dedicata per l'accesso ai dati a livello di programmazione. Ci sono diversi motivi per cui scraping web dovrebbe essere l'ultima risorsa:
Comprendiamo cosa stiamo affrontando, esaminando l'output di alcuni codici di applicazioni Web comuni. Nell'articolo Introduzione a Vagrant, ci sono alcuni commenti di Disqus nella parte inferiore della pagina:
Per poter analizzare questi commenti, dobbiamo prima trovarli sulla pagina.
Ogni browser sin dall'alba dei tempi (anni '90) ha supportato la possibilità di visualizzare l'HTML della pagina corrente. Ecco uno snippet dalla sorgente della vista di Introduzione a Vagrant che inizia con una grossa porzione di JavaScript minorato e snellito non correlato all'articolo stesso. Ecco un piccolo parte di esso:
Ecco alcuni HTML effettivi dalla pagina:
Questo sembra abbastanza disordinato, ma ciò che sorprende è che non troverete i commenti di Disqus nell'origine della pagina.
Si scopre che la pagina è un mashup e che i commenti di Disqus sono incorporati come elementi iframe (inline frame). Puoi scoprirlo facendo clic con il pulsante destro del mouse nell'area dei commenti e vedrai che ci sono informazioni sul frame e la fonte lì:
Ciò ha senso. Incorporare contenuti di terze parti come iframe è uno dei motivi principali per utilizzare gli iframe. Cerchiamo il etichetta quindi nel sorgente della pagina principale. Sventato di nuovo! Non c'è
tag nella sorgente della pagina principale.
La ragione di questa omissione è quella visualizza l'origine della pagina
mostra il contenuto che è stato prelevato dal server. Ma il DOM finale (modello oggetto documento) che viene reso dal browser può essere molto diverso. JavaScript inizia e può manipolare il DOM a piacimento. L'iframe non può essere trovato, perché non era lì quando la pagina è stata recuperata dal server.
Lo scraping statico ignora JavaScript. Raccoglie le pagine Web dal server senza l'aiuto di un browser. Ottieni esattamente ciò che vedi in "Visualizza sorgente pagina", e poi lo affetti e lo taglia. Se il contenuto che stai cercando è disponibile, non devi andare oltre. Tuttavia, se il contenuto è qualcosa come i iframe di Disqus, è necessario lo scraping dinamico.
Lo scraping dinamico utilizza un browser effettivo (o un browser headless) e consente a JavaScript di fare le sue cose. Quindi, interroga il DOM per estrarre il contenuto che sta cercando. A volte è necessario automatizzare il browser simulando un utente per ottenere il contenuto necessario.
Vediamo come funziona lo scraping statico usando due fantastici pacchetti Python: richieste per il recupero di pagine Web e BeautifulSoup per l'analisi di pagine HTML.
Installare prima pipenv, quindi: pipenv installa richieste beautifulsoup4
Questo creerà un ambiente virtuale anche per te. Se stai usando il codice di gitlab, puoi farlo installazione di pipenv
.
Il recupero di una pagina con richieste è una sola: r = requests.get (url)
L'oggetto risposta ha molti attributi. I più importanti sono ok
e soddisfare
. Se la richiesta fallisce allora r.ok
sarà falso e r.content
conterrà l'errore. Il contenuto è un flusso di byte. Di solito è meglio decodificarlo in utf-8 quando si ha a che fare con il testo:
>>> r = requests.get ('http://www.c2.com/no-such-page') >>> r.ok False >>> print (r.content.decode ('utf-8' ))404 non trovato Non trovato
L'URL / ggg richiesto non è stato trovato su questo server.
Server Apache / 2.0.52 (CentOS) su www.c2.com Porta 80
Se tutto va bene allora r.content
conterrà la pagina web richiesta (come l'origine della pagina di visualizzazione).
Il get_page ()
la funzione seguente recupera una pagina Web per URL, la decodifica in UTF-8 e la analizza in un oggetto BeautifulSoup utilizzando l'analizzatore HTML.
def get_page (url): r = requests.get (url) content = r.content.decode ('utf-8') restituisce BeautifulSoup (content, 'html.parser')
Una volta che abbiamo un oggetto BeautifulSoup, possiamo iniziare a estrarre informazioni dalla pagina. BeautifulSoup offre molte funzioni di ricerca per individuare elementi all'interno della pagina e eseguire il drill down di elementi nidificati profondi.
Tuts + pagine dell'autore contengono più tutorial. Ecco la mia pagina dell'autore. In ogni pagina ci sono fino a 12 tutorial. Se hai più di 12 tutorial, puoi passare alla pagina successiva. L'HTML per ogni articolo è racchiuso in un etichetta. La seguente funzione trova tutti gli elementi dell'articolo nella pagina, esegue il drill down nei relativi collegamenti ed estrae l'attributo href per ottenere l'URL del tutorial:
def get_page_articles (page): elements = page.findAll ('article') articles = [e.a.attrs ['href'] per e negli elementi] articoli di ritorno
Il codice seguente recupera tutti gli articoli dalla mia pagina e li stampa (senza il prefisso comune):
page = get_page ('https://tutsplus.com/authors/gigi-sayfan') articles = get_page_articles (page) prefix = 'https://code.tutsplus.com/tutorials' per a in articoli: print (a [ len (prefisso):]) Output: building-games-with-python-3-and-pygame-part-5 - cms-30085 building-games-with-python-3-and-pygame-part-4-- cms-30084 building-games-with-python-3-and-pygame-part-3 - cms-30083 building-games-with-python-3-and-pygame-part-2 - cms-30082 giochi di costruzione -with-python-3-and-pygame-part-1 - cms-30081 mastering-the-react-lifecycle-methods - cms-29849 testing-data-intensive-code-with-go-part-5-- cms-29852 testing-data-intensive-code-with-go-part-4 - cms-29851 testing-data-intensive-code-with-go-part-3 - cms-29850 test-data-intensive-code -with-go-part-2 - cms-29848 testing-data-intensive-code-with-go-part-1 - cms-29847 make-your-go-programs-lightning-fast-with-profiling-- CMS-29809
Lo scraping statico è stato sufficiente per ottenere l'elenco degli articoli, ma come abbiamo visto in precedenza, i commenti di Disqus sono incorporati come un elemento iframe da JavaScript. Per raccogliere i commenti, sarà necessario automatizzare il browser e interagire con il DOM in modo interattivo. Uno dei migliori strumenti per il lavoro è il selenio.
Il selenio è principalmente orientato verso test automatici di applicazioni Web, ma è ottimo come strumento di automazione del browser per tutti gli usi.
Digita questo comando per installare Selenium: pipenv installa il selenio
Selenium ha bisogno di un driver web (il browser che automatizza). Per il web scraping, di solito non importa quale driver scegli. Preferisco il driver Chrome. Segui le istruzioni in questa guida del selenio.
In alcuni casi è preferibile utilizzare un browser headless, il che significa che non viene visualizzata alcuna interfaccia utente. In teoria, PhantomJS è solo un altro driver web. Ma, in pratica, le persone hanno segnalato problemi di incompatibilità in cui Selenium funziona correttamente con Chrome o Firefox e talvolta fallisce con PhantomJS. Preferisco rimuovere questa variabile dall'equazione e utilizzare un vero driver web del browser.
Facciamo un po 'di scraping dinamico e usiamo il Selenium per contare i commenti di Disqus sui tutorial di Tuts +. Ecco le importazioni necessarie.
da selenio import webdriver da selenium.webdriver.common.by import Da selenium.webdriver.support.expected_conditions import (presence_of_element_located) da selenium.webdriver.support.wait import WebDriverWait
Il get_comment_count ()
la funzione accetta un driver e un URL Selenium. Usa il ottenere()
metodo del driver per recuperare l'URL. Questo è simile a requests.get ()
, ma la differenza è che l'oggetto driver gestisce una rappresentazione dal vivo del DOM.
Quindi, ottiene il titolo del tutorial e individua l'iframe Disqus utilizzando il suo id genitore disqus_thread
e poi l'iframe stesso:
def get_comment_count (driver, url): driver.get (url) class_name = 'content-banner__title' name = driver.find_element_by_class_name (class_name) .text e = driver.find_element_by_id ('disqus_thread') disqus_iframe = e.find_element_by_tag_name ('iframe' ) iframe_url = disqus_iframe.get_attribute ('src')
Il prossimo passo è recuperare il contenuto dell'iframe stesso. Nota che aspettiamo il commento-count
elemento presente perché i commenti sono caricati dinamicamente e non necessariamente ancora disponibili.
driver.get (iframe_url) wait = WebDriverWait (driver, 5) commentCountPresent = presence_of_element_located ((By.CLASS_NAME, 'comment-count')) wait.until (commentCountPresent) comment_count_span = driver.find_element_by_class_name ('comment-count') comment_count = int (comment_count_span.text.split () [0])
L'ultima parte è di restituire l'ultimo commento se non è stato creato da me. L'idea è di rilevare i commenti a cui non ho ancora risposto.
last_comment = se comment_count> 0: e = driver.find_elements_by_class_name ('autore') [- 1] last_author = e.find_element_by_tag_name ('a') last_author = e.get_attribute ('data-username') se last_author! = ' the_gigi ': e = driver.find_elements_by_class_name (' post-meta ') meta = e [-1] .find_element_by_tag_name (' a ') last_comment = dict (autore = last_author, title = meta.get_attribute (' title '), when = meta.text) restituisce nome, comment_count, last_comment
Lo scraping Web è una pratica utile quando le informazioni necessarie sono accessibili tramite un'applicazione Web che non fornisce un'API appropriata. Ci vuole un lavoro non banale per estrarre dati dalle moderne applicazioni web, ma strumenti maturi e ben progettati come le richieste, BeautifulSoup e Selenium ne fanno la pena.
Inoltre, non esitate a vedere ciò che abbiamo a disposizione per la vendita e per studiare nel mercato Envato, e non esitate a fare domande e fornire il vostro prezioso feedback utilizzando il feed qui sotto.