Come costruire un web crawler di base per estrarre informazioni da un sito web

Come costruire un web crawler di base per estrarre informazioni da un sito web / Programmazione

Hai mai desiderato di acquisire a livello di codice informazioni specifiche da un sito Web per ulteriori elaborazioni? Dì qualcosa come i risultati sportivi, le tendenze del mercato azionario o l'ultima moda, bitcoin e altri prezzi in criptovaluta? Se le informazioni necessarie sono disponibili su un sito Web, è possibile scrivere un crawler (noto anche come raschietto o spider) per navigare nel sito Web ed estrarre solo ciò di cui si ha bisogno. Cerchiamo di scoprire come farlo in Python.

Si noti che diversi siti Web scoraggiano l'utilizzo di un crawler per accedere alle informazioni fornite dal sito Web. Quindi, per favore controlla i termini e le condizioni del sito prima di implementare un crawler su qualsiasi sito web.

Installazione di Scrapy

Usiamo un modulo python chiamato Scrapy per gestire la scansione reale. È veloce, semplice e può navigare su più pagine web come è possibile con un browser.

Si noti, tuttavia, che scrapy non ha strutture per elaborare javascript durante la navigazione del sito. Pertanto, i siti Web e le app che utilizzano javascript per manipolare l'interfaccia utente non possono essere sottoposti a scansione corretta con questo approccio.

Cerchiamo di installare scrapy. Usiamo virtualenv Impara come usare l'ambiente virtuale Python Impara come usare l'ambiente virtuale Python Se sei uno sviluppatore Python esperto, o sei appena iniziato, imparare come configurare un ambiente virtuale è essenziale per qualsiasi progetto Python. Leggi di più per installare scrapy. Questo ci consente di installare scrapy in una directory senza influenzare altri moduli installati sul sistema.

Crea una directory e inizializza un ambiente virtuale in quella directory.

mkdir crawler cd crawler virtualenv venv. venv / bin / activate 

Ora puoi installare scrapy in questa directory.

pip installa scrapy 

Controlla che scrapy sia installato correttamente.

scrapy # prints Scrapy 1.4.0 - nessun progetto attivo Uso: scrapy  [opzioni] [args] Comandi disponibili: bench Esegui test di benchmark rapido Recupera un URL utilizzando il downloader di Scrapy genspider Genera un nuovo spider utilizzando template predefiniti runpider Esegui uno spider autonomo (senza creare un progetto) ... 

Costruire un crawler sito Web (chiamato anche un ragno)

Cerchiamo ora di scrivere un crawler per caricare alcune informazioni. Iniziamo raschiando alcune informazioni da una pagina di Wikipedia su una batteria da https://en.wikipedia.org/wiki/Battery_(electricity).

Il primo passo per scrivere un crawler è definire una classe python da cui si estrae scrapy.Spider. Chiamiamo questa classe spider1.

Come minimo, una classe spider richiede quanto segue:

  • un nome per identificare il ragno, “Wikipedia” in questo caso.
  • un start_urls variabile contenente un elenco di URL da cui iniziare la scansione. Usiamo l'URL di Wikipedia mostrato sopra per la nostra prima scansione.
  • un parse () metodo che - anche se per ora no-op - è usato per elaborare la pagina web per estrarre ciò che vogliamo.
import scrapy class spider1 (scrapy.Spider): name = 'Wikipedia' start_urls = ['https://en.wikipedia.org/wiki/Battery_(electricity)'] def parse (auto, risposta): pass 

Ora possiamo eseguire questo spider per garantire che tutto funzioni correttamente. Viene eseguito come segue.

scrapy runpider spider1.py # prints 2017-11-23 09:09:21 [scrapy.utils.log] INFO: Scrapy 1.4.0 avviato (bot: scrapybot) 23/11/2019 09:09:21 [scrapy.utils .log] INFO: Impostazioni sovrascritte: 'SPIDER_LOADER_WARN_ONLY': True 23-11-2017 09:09:21 [scrapy.middleware] INFO: Estensioni abilitate: ['scrapy.extensions.memusage.MemoryUsage', 'scrapy.extensions .logstats.LogStats', ... 

Disattivazione della registrazione

Come puoi vedere, l'uso di scrapy con la nostra classe minimale genera un mucchio di output che per noi non ha molto senso. Permettici di impostare il livello di registrazione su avvertimento e riprovare. Aggiungi le seguenti righe all'inizio del file.

registrazione di importazione logging.getLogger ('scrapy'). setLevel (logging.WARNING) 

Durante il rieseguimento dello spider, dovremmo vedere almeno i messaggi del registro.

Utilizzo di Chrome Inspector

L'estrazione di informazioni da una pagina Web consiste nel determinare la posizione dell'elemento HTML da cui vogliamo le informazioni. Un modo semplice e divertente per trovare la posizione di un elemento Figura fuori dai problemi del sito Web con gli strumenti per sviluppatori di Chrome o Firebug Scopri i problemi del sito web con gli strumenti per sviluppatori di Chrome o Firebug Se hai seguito i miei tutorial su jQuery finora, potresti aver già incontrato alcuni problemi di codice e non so come risolverli. Di fronte a un bit di codice non funzionale, è molto ... Leggi altro dal browser Web di Chrome è utilizzare Inspector.

  • Passa alla pagina corretta in Chrome.
  • Posiziona il mouse sull'elemento per il quale vuoi le informazioni.
  • Fai clic con il pulsante destro del mouse per visualizzare il menu di scelta rapida.
  • Selezionare Ispezionare dal menu.

Dovrebbe apparire la console di sviluppo con il Elementi scheda selezionata. Sotto la scheda, dovresti vedere la barra di stato con la posizione dell'elemento mostrato come segue:

html body div # content.mw-body h1 # firstHeading.firstHeading.

Come spieghiamo di seguito, hai bisogno di alcune o tutte le parti di questa posizione.

Estrazione del titolo

Aggiungiamo ora un po 'di codice al parse () metodo per estrarre il titolo della pagina.

... def parse (self, response): print response.css ('h1 # firstHeading :: text'). Extract () ... 

Il risposta l'argomento del metodo supporta un metodo chiamato css () che seleziona gli elementi dalla pagina usando la posizione data. Per il nostro caso, l'elemento è h1.firstHeading. Abbiamo bisogno del contenuto testuale dell'elemento, quindi aggiungiamo ::testo alla selezione. Finalmente, il estratto() metodo restituisce l'elemento selezionato.

In esecuzione di scrapy ancora una volta su questa classe, otteniamo il seguente risultato:

[u'Batteria (elettricità) '] 

Questo mostra che il titolo è stato estratto in un elenco di stringhe Unicode.

Come sulla descrizione?

Per dimostrare alcuni altri aspetti dell'estrazione dei dati dalle pagine Web, prendiamo il primo paragrafo della descrizione dalla pagina Wikipedia di cui sopra.

Durante l'ispezione utilizzando la Console per gli sviluppatori di Chrome, scopriamo che la posizione dell'elemento è (la parentesi angolare destra (>) indica una relazione genitore-figlio tra gli elementi):

div # mw-content-text> div> p

Questa posizione restituisce tutti il p elementi abbinati, che include l'intera descrizione. Dal momento che vogliamo solo il primo p elemento, usiamo il seguente estrattore:

response.css ( 'div # mw-content-text> div> p') [0] 

Per estrarre solo il contenuto del testo, aggiungiamo l'estrattore CSS ::testo:

response.css ( 'div # mw-content-text> div> p') [0] .css ( ':: text') 

L'espressione finale usa estratto() che restituisce un elenco di stringhe Unicode. Usiamo il pitone aderire() funzione per unire l'elenco.

 def parse (self, response): stampa ".join (response.css ('div # mw-content-text> div> p') [0] .css (':: text'). extract ()) 

L'output di scrapy in esecuzione con questa classe è quello che stiamo cercando:

Una batteria elettrica è un dispositivo costituito da una o più celle elettrochimiche con connessioni esterne fornite per alimentare dispositivi elettrici quali torce elettriche, smartphone e auto elettriche. [1] Quando una batteria fornisce energia elettrica, il suo terminale positivo è ... 

Raccolta dati usando dare la precedenza

Il codice sopra riportato stampa i dati estratti sulla console. Quando è necessario raccogliere dati come JSON, è possibile utilizzare il dare la precedenza dichiarazione. La via dare la precedenza funziona come segue: eseguendo una funzione che contiene a dare la precedenza l'istruzione restituisce ciò che è noto come generatore al chiamante. Il generatore è una funzione che il chiamante può eseguire ripetutamente fino alla sua conclusione.

Ecco un codice simile al precedente, ma che usa il dare la precedenza dichiarazione per restituire la lista di p elementi all'interno dell'HTML.

... def parse (self, response): per e in response.css ('div # mw-content-text> div> p'): yield 'para': ". Join (e.css (':: testo' ) .extract ()). strip () ... 

Ora puoi eseguire lo spider specificando un file JSON di output come segue:

runpider scrapy spider3.py -o joe.json 

L'output generato è il seguente:

["para": "Una batteria elettrica è un dispositivo costituito da una o più celle elettrochimiche con connessioni esterne fornite per alimentare dispositivi elettrici quali torce elettriche, smartphone e auto elettriche. [1] Quando una batteria fornisce energia elettrica, terminale positivo è il catodo e il suo terminale negativo è l'anodo. [2] Il terminale contrassegnato come negativo è la sorgente di elettroni che quando collegati a un circuito esterno fluiscono e forniscono energia a un dispositivo esterno. circuito, gli elettroliti sono in grado di muoversi come ioni all'interno, consentendo alle reazioni chimiche di essere completate ai terminali separati e quindi di fornire energia al circuito esterno.È il movimento di quegli ioni all'interno della batteria che consente alla corrente di fluire dalla batteria per eseguire il lavoro. [3] Storicamente il termine \ "batteria \" si riferiva specificamente a un dispositivo composto da più celle, tuttavia l'uso si è evoluto ulteriormente per includere dispositivi composti da un [4] ", " para ":" Le batterie primarie (monouso o \ "usa e getta \") vengono usate una volta e scartate; i materiali degli elettrodi sono cambiati irreversibilmente durante la scarica. Esempi comuni sono la batteria alcalina utilizzata per torce elettriche e una moltitudine di dispositivi elettronici portatili. Le batterie secondarie (ricaricabili) possono essere scaricate e ricaricate più ... 

Elaborazione di più bit di informazioni

Cerchiamo ora di estrarre più bit relativi alle informazioni. Per questo esempio, estrarremo i migliori successi del Box office di IMDb per il fine settimana in corso. Queste informazioni sono disponibili all'indirizzo http://www.imdb.com/chart/boxoffice, in una tabella con una riga di informazioni per ogni hit.

Estraiamo vari campi in ogni riga usando il seguente parse () metodo. Anche in questo caso, le posizioni CSS dell'elemento sono state determinate utilizzando la Developer Console di Chrome come spiegato sopra:

... def parse (self, response): per e in response.css ('div # boxoffice> tabella> tbody> tr'): yield 'title': ". Join (e.css ('td.titleColumn> a: : text '). extract ()). strip (),' weekend ': ". join (e.css (' td.ratingColumn ') [0] .css (' :: text '). extract ()). strip (), 'gross': ". join (e.css ('td.ratingColumn') [1] .css ('span.secondaryInfo :: text'). extract ()). strip (), 'weeks' : ". join (e.css ('td.weeksColumn :: text'). extract ()). strip (), 'image': e.css ('td.posterColumn img :: attr (src)'). extract_first (), ... 

Si noti che il Immagine il selettore sopra lo specifica img è un discendente di td.posterColumn, e stiamo estraendo l'attributo chiamato src usando l'espressione :: attr (src).

L'esecuzione dello spider ora restituisce il seguente JSON:

["lordo": "$ 93,8 milioni", "settimane": "1", "fine settimana": "$ 93,8 milioni", "immagine": "https://images-na.ssl-images-amazon.com/images /M/MV5BYWVhZjZkYTItOGIwYS00NmRkLWJlYjctMWM0ZjFmMDU4ZjEzXkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_UY67_CR0,0,45,67_AL_.jpg "," titolo ":" Justice League ", " lordo ":" $ 27,5 M "," settimane ":" 1 "," fine settimana ":" $ 27,5 M "," immagine ":" https://images-na.ssl-images-amazon.com/images/M/MV5BYjFhOWY0OTgtNDkzMC00YWJkLTk1NGEtYWUxNjhmMmQ5ZjYyXkEyXkFqcGdeQXVyMjOT_0O0@._V1_UX45_CR0,0,45,67_AL_.jpg "," titolo ":" Meraviglia " , "lordo": "$ 247,3 milioni", "settimane": "3", "fine settimana": "$ 21,7 milioni", "immagine": "https://images-na.ssl-images-amazon.com/ images / M / MV5BMjMyNDkzMzI1OF5BMl5BanBnXkFtZTgwODcxODg5MjI @ ._ V1_UY67_CR0,0,45,67_AL_.jpg "," titolo ":" Thor: Ragnarok ", ...] 

Utilizzo del tuo crawler

Consentitemi ora di concludere questo articolo con alcuni punti salienti:

  • L'utilizzo di python con scrapy semplifica la scrittura dei crawler dei siti Web per estrarre le informazioni necessarie.
  • La Console per gli sviluppatori di Chrome (o lo strumento Firebug di Firefox) aiuta a localizzare le posizioni degli elementi da estrarre.
  • Python dare la precedenza la dichiarazione aiuta ad estrarre elementi di dati ripetuti.

Hai in mente progetti specifici per il scraping del sito web? E quali problemi hai affrontato cercando di farlo funzionare? Per favore fateci sapere nei commenti qui sotto.

Immagine di credito: dxinerz / Depositphotos | Lulzmango / Wikimedia Commons

Scopri di più su: Programmazione, Python, Strumenti per i Webmaster.