Come creare un crawler Web di base per estrarre informazioni da un sito Web

I programmi che leggono informazioni da siti Web o crawler Web dispongono di tutti i tipi di applicazioni utili. Puoi raccogliere informazioni su titoli, risultati sportivi, testo da un account Twitter o ricavare prezzi dai siti Web di shopping.

Scrivere questi programmi di scansione web è più facile di quanto si pensi. Python ha un'ottima libreria per la scrittura di script che estraggono informazioni dai siti Web. Diamo un'occhiata a come creare un web crawler usando Scrapy.

Installazione di Scrapy

Scrapy è una libreria Python creata per raschiare il web e creare crawler web. È veloce, semplice e può navigare attraverso più pagine Web senza troppi sforzi.

Scrapy è disponibile attraverso la libreria Pip Python (PIP) di installazione , ecco un aggiornamento su come installare PIP su Windows, Mac e Linux .

L'utilizzo di un ambiente virtuale Python è preferibile perché consentirà di installare Scrapy in una directory virtuale che lascia soli i file di sistema. La documentazione di Scrapy consiglia di farlo per ottenere i migliori risultati.

Creare una directory e inizializzare un ambiente virtuale.

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

Ora puoi installare Scrapy in quella directory usando un comando PIP.

 pip install scrapy 

Un rapido controllo per assicurarsi che Scrapy sia installato correttamente

 scrapy # prints Scrapy 1.4.0 - no active project Usage: scrapy <command> [options] [args] Available commands: bench Run quick benchmark test fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates runspider Run a self-contained spider (without creating a project) ... 

Come costruire un web crawler

Ora che l'ambiente è pronto, puoi iniziare a creare il web crawler. Raccogliamo alcune informazioni da una pagina di Wikipedia sulle batterie: https://en.wikipedia.org/wiki/Battery_(elettricità) .

Il primo passo per scrivere un crawler è definire una classe Python che si estende da Scrapy.Spider . Ciò ti dà accesso a tutte le funzioni e caratteristiche di Scrapy. Chiamiamo questa classe spider1 .

Una classe di ragno ha bisogno di alcune informazioni:

  • un nome per identificare il ragno
  • una variabile start_urls contenente un elenco di URL da cui eseguire la scansione (l'URL di Wikipedia sarà l'esempio in questo tutorial)
  • un metodo parse () utilizzato per elaborare la pagina Web per estrarre informazioni
 import scrapy class spider1(scrapy.Spider): name = 'Wikipedia' start_urls = ['https://en.wikipedia.org/wiki/Battery_(electricity)'] def parse(self, response): pass 

Un test rapido per assicurarsi che tutto funzioni correttamente.

 scrapy runspider spider1.py # prints 2017-11-23 09:09:21 [scrapy.utils.log] INFO: Scrapy 1.4.0 started (bot: scrapybot) 2017-11-23 09:09:21 [scrapy.utils.log] INFO: Overridden settings: {'SPIDER_LOADER_WARN_ONLY': True} 2017-11-23 09:09:21 [scrapy.middleware] INFO: Enabled extensions: ['scrapy.extensions.memusage.MemoryUsage', 'scrapy.extensions.logstats.LogStats', ... 

Disattivazione della registrazione

L'esecuzione di Scrapy con questa classe stampa informazioni di registro che non ti aiuteranno in questo momento. Rendiamolo semplice rimuovendo queste informazioni di registro in eccesso. Utilizzare un'istruzione di avviso aggiungendo codice all'inizio del file.

 import logging logging.getLogger('scrapy').setLevel(logging.WARNING) 

Ora, quando si esegue nuovamente lo script, le informazioni del registro non verranno stampate.

Utilizzo di Chrome Inspector

Tutto in una pagina Web è archiviato in elementi HTML. Gli elementi sono disposti nel Document Object Model (DOM). Comprendere il DOM è fondamentale per ottenere il massimo dal tuo crawler web. Un crawler web cerca in tutti gli elementi HTML di una pagina per trovare informazioni, quindi è importante sapere come sono organizzati.

Google Chrome ha strumenti che ti aiutano a trovare gli elementi HTML più velocemente. Puoi trovare l'HTML per qualsiasi elemento che vedi sulla pagina web usando inspector.

  • Vai a una pagina in Chrome
  • Posiziona il mouse sull'elemento che desideri visualizzare
  • Fare clic con il tasto destro del mouse e selezionare Ispeziona dal menu

Questi passaggi apriranno la console per sviluppatori con la scheda Elementi selezionata. Nella parte inferiore della console, vedrai un albero di elementi. Questo albero è il modo in cui otterrai informazioni per il tuo script.

Estrarre il titolo

Facciamo in modo che la sceneggiatura faccia del lavoro per noi; Una semplice scansione per ottenere il testo del titolo della pagina Web.

Avvia lo script aggiungendo del codice al metodo parse () che estrae il titolo.

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

L'argomento response supporta un metodo chiamato CSS () che seleziona gli elementi dalla pagina utilizzando la posizione fornita.

In questo esempio, l'elemento è h1.firstHeading . L'aggiunta di ::text allo script è ciò che ti dà il contenuto testuale dell'elemento. Infine, il metodo extract () restituisce l'elemento selezionato.

L'esecuzione di questo script in Scrapy stampa il titolo in formato testo.

 [u'Battery (electricity)'] 

Trovare la descrizione

Ora che abbiamo cancellato il testo del titolo, facciamo di più con lo script. Il crawler troverà il primo paragrafo dopo il titolo ed estrarrà queste informazioni.

Ecco l'albero degli elementi nella Console per gli sviluppatori di Chrome:

 div#mw-content-text>div>p 

La freccia destra (>) indica una relazione genitore-figlio tra gli elementi.

Questa posizione restituirà tutti gli elementi p corrispondenti, che include l'intera descrizione. Per ottenere il primo elemento p puoi scrivere questo codice:

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

Proprio come il titolo, aggiungi CSS extractor ::text per ottenere il contenuto testuale dell'elemento.

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

L'espressione finale utilizza extract () per restituire l'elenco. È possibile utilizzare la funzione join () di Python per unirsi all'elenco una volta completata la ricerca per indicizzazione.

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

Il risultato è il primo paragrafo del testo!

 An electric battery is a device consisting of one or more electrochemical cells with external connections provided to power electrical devices such as flashlights, smartphones, and electric cars.[1] When a battery is supplying electric power, its positive terminal is ... 

Raccolta di dati JSON

Scrapy può estrarre informazioni in forma di testo, il che è utile. Scrapy ti consente anche di visualizzare i dati JavaScript Object Notation (JSON). JSON è un modo semplice per organizzare le informazioni ed è ampiamente utilizzato nello sviluppo web. JSON funziona abbastanza bene anche con Python .

Quando è necessario raccogliere dati come JSON, è possibile utilizzare la dichiarazione di rendimento integrata in Scrapy.

Ecco una nuova versione dello script che utilizza un'istruzione yield. Invece di ottenere il primo elemento p in formato testo, questo prenderà tutti gli elementi p e lo organizzerà in formato JSON.

 ... def parse(self, response): for e in response.css('div#mw-content-text>div>p'): yield { 'para' : ''.join(e.css('::text').extract()).strip() } ... 

Ora puoi eseguire il ragno specificando un file JSON di output:

 scrapy runspider spider3.py -o joe.json 

Lo script ora stamperà tutti gli elementi p.

 [ {"para": "An electric battery is a device consisting of one or more electrochemical cells with external connections provided to power electrical devices such as flashlights, smartphones, and electric cars.[1] When a battery is supplying electric power, its positive terminal is the cathode and its negative terminal is the anode.[2] The terminal marked negative is the source of electrons that when connected to an external circuit will flow and deliver energy to an external device. When a battery is connected to an external circuit, electrolytes are able to move as ions within, allowing the chemical reactions to be completed at the separate terminals and so deliver energy to the external circuit. It is the movement of those ions within the battery which allows current to flow out of the battery to perform work.[3] Historically the term "battery" specifically referred to a device composed of multiple cells, however the usage has evolved additionally to include devices composed of a single cell.[4]"}, {"para": "Primary (single-use or "disposable") batteries are used once and discarded; the electrode materials are irreversibly changed during discharge. Common examples are the alkaline battery used for flashlights and a multitude of portable electronic devices. Secondary (rechargeable) batteries can be discharged and recharged multiple ... 

Raschiare più elementi

Finora il web crawler ha eliminato il titolo e un tipo di elemento dalla pagina. Scrapy può anche estrarre informazioni da diversi tipi di elementi in uno script.

Estraiamo i migliori successi del Box office di IMDb per un weekend. Questa informazione viene estratta da http://www.imdb.com/chart/boxoffice , in una tabella con righe per ogni metrica.

Il metodo parse () può estrarre più di un campo dalla riga. Utilizzando gli Strumenti per sviluppatori di Chrome puoi trovare gli elementi nidificati all'interno della tabella.

 ... def parse(self, response): for e in response.css('div#boxoffice>table>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(), } ... 

Il selettore di immagini specifica che img è un discendente di td.posterColumn . Per estrarre l'attributo giusto, usa l'espressione ::attr(src) .

L'esecuzione del ragno restituisce JSON:

 [ {"gross": "$93.8M", "weeks": "1", "weekend": "$93.8M", "image": "https://images-na.ssl-images-kelkoo.it/cerca?richiesta=images/M/MV5BYWVhZjZkYTIt[email protected]._V1_UY67_CR0,0,45,67_AL_.jpg", "title": "Justice League"}, {"gross": "$27.5M", "weeks": "1", "weekend": "$27.5M", "image": "https://images-na.ssl-images-kelkoo.it/cerca?richiesta=images/M/MV5BYjFhOWY0OTgt[email protected]._V1_UX45_CR0,0,45,67_AL_.jpg", "title": "Wonder"}, {"gross": "$247.3M", "weeks": "3", "weekend": "$21.7M", "image": "https://images-na.ssl-images-kelkoo.it/cerca?richiesta=images/M/[email protected]_V1_UY67_CR0,0,45,67_AL_.jpg", "title": "Thor: Ragnarok"}, ... ] 

Più web raschiatori e robot

Scrapy è una libreria dettagliata che può eseguire praticamente qualsiasi tipo di scansione del Web a cui lo chiedi. Quando si tratta di trovare informazioni negli elementi HTML, in combinazione con il supporto di Python, è difficile da battere. Che tu stia costruendo un web crawler o apprendendo le basi del web scraping, l'unico limite è quanto sei disposto a imparare.

Se stai cercando altri modi per costruire crawler o bot, puoi provare a costruire bot Twitter e Instagram usando Python . Python è in grado di creare cose straordinarie nello sviluppo web , quindi vale la pena andare oltre i web crawler quando si esplora questo linguaggio.

Leggi l'articolo completo: Come creare un crawler Web di base per estrarre informazioni da un sito Web