Qual è il modo migliore per estrarre dati da un sito web? [chiuso]


107

Devo estrarre i contenuti da un sito Web, ma l'applicazione non fornisce alcuna interfaccia di programmazione dell'applicazione o un altro meccanismo per accedere a tali dati a livello di codice.

Ho trovato un utile strumento di terze parti chiamato Import.io che fornisce funzionalità click and go per lo scraping di pagine Web e la creazione di set di dati, l'unica cosa è che voglio mantenere i miei dati localmente e non voglio iscrivermi a nessun piano di abbonamento .

Che tipo di tecnica utilizza questa azienda per raschiare le pagine web e creare i propri set di dati? Ho scoperto che alcuni framework di web scraping pjscrape e Scrapy potrebbero fornire una tale funzionalità


4
PHP non è certamente fuori discussione, ovviamente è sbagliato. gist.github.com/krakjoe/b1526fcc828621e840cb
Joe Watkins

@ JoeWatkins sembra davvero interessante, ha bisogno di una configurazione PHP speciale per funzionare? E come è la performance rispetto agli strumenti / linguaggi forniti di seguito?
0x1ad2

1
Richiede una build thread-safe di PHP e pthreads, leggi github.com/krakjoe/pthreads/blob/master/README.md , puoi trovarmi in chat se vuoi aiuto, me o chiunque altro :)
Joe Watkins

@ 0x1ad2 Se vuoi mantenere i dati localmente, dovresti provare il software ( datascraping.co ) invece delle API web. La maggior parte degli strumenti utilizza Xpath, CSS selector e REGEX per estrarre i dati dai siti Web e Data Scraping Studio supporta tutte queste 3 funzionalità.
Vikash Rathee

Ci sono due modi, uno è quello di implementare il tuo utilizzando librerie gratuite / open source che richiedono molto impegno. Puoi letteralmente generare un web crawler ajax per qualsiasi sito usando scrape.it È uno strumento a pagamento ma ha funzionato quando nessuno dei due strumenti gratuiti come import.io o kimono potevano eseguire il rendering.
I Love Python

Risposte:


271

Avrai sicuramente voglia di iniziare con un buon framework di web scraping. In seguito potresti decidere che sono troppo limitanti e puoi mettere insieme la tua pila di librerie ma senza molta esperienza di scraping il tuo design sarà molto peggio di pjscrape o scrapy.

Nota: utilizzo i termini scansione e raschiatura sostanzialmente intercambiabili qui. Questa è una copia della mia risposta alla tua domanda su Quora, è piuttosto lunga.

Utensili

Acquisisci familiarità con gli strumenti di sviluppo Firebug o Chrome a seconda del tuo browser preferito. Ciò sarà assolutamente necessario mentre navighi nel sito da cui stai estraendo i dati e mappando quali URL contengono i dati che stai cercando e quali formati di dati compongono le risposte.

Avrai bisogno di una buona conoscenza di HTTP oltre che di HTML e probabilmente vorrai trovare un buon pezzo di uomo nel software proxy intermedio. Dovrai essere in grado di ispezionare le richieste e le risposte HTTP e capire come vengono passati i cookie, le informazioni sulla sessione ei parametri di query. Fiddler ( http://www.telerik.com/fiddler ) e Charles Proxy ( http://www.charlesproxy.com/ ) sono strumenti popolari. Uso molto mitmproxy ( http://mitmproxy.org/ ) perché sono più un tipo da tastiera che da mouse.

Una sorta di ambiente di tipo console / shell / REPL in cui è possibile provare vari pezzi di codice con feedback immediato sarà inestimabile. Attività di ingegneria inversa come questa sono molte prove ed errori, quindi ti servirà un flusso di lavoro che lo renda facile.

linguaggio

PHP è praticamente fuori uso, non è adatto per questo compito e il supporto di librerie / framework è scarso in quest'area. Python (Scrapy è un ottimo punto di partenza) e Clojure / Clojurescript (incredibilmente potente e produttivo ma una grande curva di apprendimento) sono ottimi linguaggi per questo problema. Dal momento che preferiresti non imparare una nuova lingua e conosci già Javascript, ti suggerirei sicuramente di restare con JS. Non ho usato pjscrape ma sembra abbastanza buono da una rapida lettura dei loro documenti. È adatto e implementa un'ottima soluzione al problema che descrivo di seguito.

Nota sulle espressioni regolari: NON UTILIZZARE ESPRESSIONI REGOLARI PER PARSE HTML. Molti principianti lo fanno perché hanno già familiarità con le regex. È un errore enorme, usa i selettori xpath o css per navigare in html e usa solo espressioni regolari per estrarre dati dal testo effettivo all'interno di un nodo html. Questo potrebbe già essere ovvio per te, diventa ovvio rapidamente se lo provi, ma molte persone perdono molto tempo percorrendo questa strada per qualche motivo. Non aver paura dei selettori xpath o css, sono MOLTO più facili da imparare rispetto alle regex e sono stati progettati per risolvere questo problema esatto.

Siti che utilizzano JavaScript

In passato dovevi solo fare una richiesta http e analizzare la risposta HTML. Ora dovrai quasi certamente avere a che fare con siti che sono un mix di richieste / risposte HTTP HTML standard e chiamate HTTP asincrone effettuate dalla parte javascript del sito di destinazione. È qui che il tuo software proxy e la scheda di rete di firebug / devtools sono molto utili. Le risposte a questi potrebbero essere html o potrebbero essere json, in rari casi saranno xml o qualcos'altro.

Esistono due approcci a questo problema:

L'approccio di basso livello:

Puoi capire quali URL ajax sta chiamando il javascript del sito e come appaiono quelle risposte e fai tu stesso le stesse richieste. Quindi potresti estrarre l'html da http://example.com/foobar ed estrarre un pezzo di dati e quindi dover estrarre la risposta json da http://example.com/api/baz?foo=b ... a ottenere l'altro pezzo di dati. È necessario essere consapevoli del passaggio dei cookie o dei parametri di sessione corretti. È molto raro, ma a volte alcuni parametri richiesti per una chiamata ajax saranno il risultato di alcuni calcoli folli eseguiti nel javascript del sito, il reverse engineering può essere fastidioso.

L'approccio del browser incorporato:

Perché hai bisogno di capire quali dati sono in html e quali dati provengono da una chiamata ajax? Gestisci tutta quella sessione e i dati dei cookie? Non devi farlo quando navighi in un sito, il browser e il javascript del sito lo fanno. Questo è il punto.

Se carichi la pagina in un motore di browser headless come phantomjs, caricherà la pagina, eseguirà javascript e ti dirà quando tutte le chiamate ajax sono state completate. Puoi inserire il tuo javascript se necessario per attivare i clic appropriati o qualsiasi cosa sia necessaria per attivare il javascript del sito per caricare i dati appropriati.

Ora hai due opzioni, fai in modo che sputi l'html finito e lo analizzi o inserisci un po 'di javascript nella pagina che esegue l'analisi e la formattazione dei dati e sputa i dati (probabilmente in formato json). Puoi anche combinare liberamente queste due opzioni.

Qual è l'approccio migliore?

Dipende, dovrai sicuramente avere familiarità e familiarità con l'approccio di basso livello. L'approccio del browser incorporato funziona per qualsiasi cosa, sarà molto più facile da implementare e farà scomparire alcuni dei problemi più complicati nello scraping. È anche un macchinario piuttosto complesso che dovrai capire. Non si tratta solo di richieste e risposte HTTP, ma anche di richieste, rendering del browser incorporato, javascript del sito, javascript iniettato, codice personale e interazione a 2 vie con il processo del browser incorporato.

Il browser incorporato è anche molto più lento su larga scala a causa del sovraccarico di rendering, ma quasi certamente non avrà importanza a meno che non si stiano raschiando molti domini diversi. La tua necessità di limitare la velocità delle tue richieste renderà il tempo di rendering completamente trascurabile nel caso di un singolo dominio.

Limitazione della velocità / comportamento del bot

Devi essere molto consapevole di questo. È necessario effettuare richieste ai domini di destinazione a una tariffa ragionevole. È necessario scrivere un bot che si comporti bene durante la scansione dei siti Web e ciò significa rispettare il file robots.txt e non martellare il server con le richieste. Errori o negligenza qui sono molto immorali poiché questo può essere considerato un attacco di negazione del servizio. Il tasso accettabile varia a seconda di chi chiedi, 1req / s è il massimo a cui viene eseguito il crawler di Google ma non sei Google e probabilmente non sei il benvenuto come Google. Tienilo il più lento ragionevole. Suggerirei 2-5 secondi tra ogni richiesta di pagina.

Identifica le tue richieste con una stringa agente utente che identifica il tuo bot e disponi di una pagina web per il tuo bot che ne spiega lo scopo. Questo URL va nella stringa dell'agente.

Sarai facile da bloccare se il sito vuole bloccarti. Un ingegnere intelligente da parte sua può identificare facilmente i bot e pochi minuti di lavoro da parte loro possono far sì che settimane di lavoro cambino il tuo codice di scraping da parte tua o semplicemente renderlo impossibile. Se la relazione è antagonistica, un ingegnere intelligente nel sito di destinazione può ostacolare completamente un ingegnere geniale che scrive un crawler. Il codice di scraping è intrinsecamente fragile e questo può essere facilmente sfruttato. Qualcosa che provocherebbe questa risposta è quasi certamente immorale comunque, quindi scrivi un bot ben educato e non preoccuparti di questo.

analisi

Non sei una persona per test di unità / integrazione? Peccato. Ora dovrai diventarlo. I siti cambiano frequentemente e tu cambierai spesso il tuo codice. Questa è una parte importante della sfida.

Ci sono molte parti mobili coinvolte nello scraping di un sito Web moderno, buone pratiche di test aiuteranno molto. Molti dei bug che incontrerai durante la scrittura di questo tipo di codice saranno del tipo che restituisce silenziosamente i dati danneggiati. Senza buoni test per verificare le regressioni, scoprirai che hai salvato dati inutili danneggiati nel tuo database per un po 'senza accorgertene. Questo progetto ti renderà molto familiare con la convalida dei dati (trova alcune buone librerie da usare) e il test. Non ci sono molti altri problemi che combinano la necessità di test completi e l'essere molto difficili da testare.

La seconda parte dei test riguarda la memorizzazione nella cache e il rilevamento delle modifiche. Mentre scrivi il tuo codice, non vuoi martellare il server per la stessa pagina più e più volte senza motivo. Mentre esegui i tuoi unit test, vuoi sapere se i tuoi test hanno esito negativo perché hai rotto il codice o perché il sito web è stato riprogettato. Esegui i tuoi unit test su una copia cache degli URL coinvolti. Un proxy per la memorizzazione nella cache è molto utile qui, ma difficile da configurare e utilizzare correttamente.

Vuoi anche sapere se il sito è cambiato. Se hanno riprogettato il sito e il tuo crawler non funziona, i tuoi unit test verranno comunque superati perché sono in esecuzione su una copia cache! Avrai bisogno di un altro set più piccolo di test di integrazione che vengono eseguiti raramente sul sito live o di una buona registrazione e rilevamento degli errori nel codice di scansione che registra i problemi esatti, ti avvisa del problema e interrompe la scansione. Ora puoi aggiornare la cache, eseguire i test unitari e vedere cosa devi cambiare.

Questioni legali

La legge qui può essere leggermente pericolosa se fai cose stupide. Se la legge viene coinvolta, hai a che fare con persone che si riferiscono regolarmente a wget e curl come "strumenti di hacking". Non lo vuoi.

La realtà etica della situazione è che non c'è differenza tra l'utilizzo del software del browser per richiedere un URL e guardare alcuni dati e l'utilizzo del proprio software per richiedere un URL e guardare alcuni dati. Google è la più grande azienda di scraping al mondo e sono amati per questo. Identificare il nome del tuo robot nell'agente utente ed essere aperto sugli obiettivi e le intenzioni del tuo crawler web aiuterà qui poiché la legge comprende cosa è Google. Se stai facendo qualcosa di losco, come creare account utente falsi o accedere ad aree del sito che non dovresti (o "bloccato" da robots.txt oa causa di qualche tipo di exploit di autorizzazione), tieni presente che stai facendo qualcosa di non etico e l'ignoranza della legge riguardo alla tecnologia sarà straordinariamente pericolosa qui. È una situazione ridicola ma è reale.

È letteralmente possibile provare a costruire un nuovo motore di ricerca come un cittadino onesto, commettere un errore o avere un bug nel tuo software ed essere visto come un hacker. Non qualcosa che vuoi considerando l'attuale realtà politica.

Comunque, chi sono io per scrivere questo gigantesco muro di testo?

Nella mia vita ho scritto molto codice relativo alla scansione del Web. Mi occupo di sviluppo di software per il web da più di un decennio come consulente, dipendente e fondatore di startup. I primi giorni scrivevano crawler / scrapers perl e siti web php. Quando incorporavamo iframe nascosti che caricavano dati csv nelle pagine web per eseguire ajax prima che Jesse James Garrett lo chiamasse ajax, prima che XMLHTTPRequest fosse un'idea. Prima di jQuery, prima di json. Ho circa trentacinque anni, sembra che sia considerato antico per questo lavoro.

Ho scritto due volte sistemi di scansione / scraping su larga scala, una volta per un grande team di un'azienda di media (in Perl) e recentemente per un piccolo team come CTO di una startup di motori di ricerca (in Python / Javascript). Attualmente lavoro come consulente, principalmente codificando in Clojure / Clojurescript (un meraviglioso linguaggio esperto in generale e ha librerie che rendono piacevoli i problemi di crawler / scraper)

Ho scritto anche sistemi software anti-crawling di successo. È straordinariamente facile scrivere siti quasi inaccessibili se lo desideri o identificare e sabotare bot che non ti piacciono.

Mi piace scrivere crawler, scrapers e parser più di qualsiasi altro tipo di software. È stimolante, divertente e può essere utilizzato per creare cose incredibili.


4
Ero d'accordo con te sul fatto che PHP sia una cattiva scelta, ma con le librerie giuste non è poi così male. La manipolazione di espressioni regolari e di matrice / puntura è goffa, ma il lato positivo è veloce e ovunque.
pguardiario

3
In un ambiente dove ci sono poche biblioteche che rendono questo un piacere e molte che lo rendono abbastanza semplice e abbastanza facile ... perché dovresti accontentarti di "non male". Sono d'accordo, è fattibile in PHP (e FORTRAN, C, VB, ecc.) Ma a meno che il tuo problema non sia davvero molto semplice, allora sarebbe un'idea molto migliore usare gli strumenti giusti per il lavoro. E ancora, a meno che tu non abbia un problema incredibilmente semplice da risolvere ... cosa importa che regex sia ovunque? L'installazione delle librerie è molto più semplice di quasi tutti i problemi di scraping. E in realtà, regex è spesso piuttosto lento per questo problema.
Jesse Sherlock

5
Forse hai ragione, ma so per certo che io non posso farlo con la stessa facilità in PHP. Prima di abbandonare PHP avevo quasi un decennio di esperienza professionale in PHP. Ho passato più di un anno a tempo pieno a costruire un sistema di scraping su larga scala, in Python, e non riesco a immaginare di fare a meno di alcune delle belle librerie che non sono disponibili in PHP o di fare a meno delle concise tecniche di meta-programmazione disponibili in Python . Questo è anche il motivo per cui sono passato a Clojure, per ottenere abilità di meta-programmazione ancora più potenti.
Jesse Sherlock

4
Enlive, insieme alla potenza di Clojure stesso per il codice specifico del progetto, sono i maggiori vincitori. Schema è un'ottima libreria di convalida, che è una parte così importante del codice di estrazione delle informazioni. Al momento sono molto soddisfatto della facile interoperabilità con il mondo Java per cose come Mahout e Nashorn / Rhino per alcuni tipi di esecuzione js. E le persone Clojure sono i tipi che scrivono librerie come questa github.com/shriphani/subotai in modo che tu non debba farlo. ... continua nel prossimo commento ...
Jesse Sherlock

3
Ho anche scoperto che quando hai davvero bisogno di un browser reale e devi andare con phantomjs / casperjs è davvero fantastico usare clojurescript (spesso codice condiviso tra clj e cljs usando cljx) per scrivere il js che inserisci nella pagina invece di clojurescript . Core.async è ottimo per coordinare codice di scansione altamente simultaneo sul server e per uscire dall'inferno di callback all'interno dell'ambiente js (coordinare l'automazione del browser con il codice cljs core.async all'interno di phantomjs è il paradiso rispetto alle alternative).
Jesse Sherlock

21

Sì, puoi farlo da solo. È solo questione di afferrare i sorgenti della pagina e analizzarli nel modo desiderato.

Ci sono varie possibilità. Una buona combinazione sta usando le richieste python (costruito sopra urllib2, è urllib.requestin Python3) e BeautifulSoup4 , che ha i suoi metodi per selezionare gli elementi e consente anche i selettori CSS :

import requests
from BeautifulSoup4 import BeautifulSoup as bs
request = requests.get("http://foo.bar")
soup = bs(request.text) 
some_elements = soup.find_all("div", class_="myCssClass")

Alcuni preferiranno l'analisi xpath o pyquery simile a jquery, lxml o qualcos'altro .

Quando i dati che desideri sono prodotti da alcuni JavaScript , quanto sopra non funzionerà. O hai bisogno di fantasma di pitone o selenio. Preferisco quest'ultimo abbinato a PhantomJS , molto più leggero e semplice da installare e facile da usare:

from selenium import webdriver
client = webdriver.PhantomJS()
client.get("http://foo")
soup = bs(client.page_source)

Consiglierei di iniziare la tua soluzione. Capirai i vantaggi di Scrapy in questo modo.

ps: dai un'occhiata a scrapely: https://github.com/scrapy/scrapely

pps: dai un'occhiata a Portia, per iniziare a estrarre informazioni visivamente, senza conoscenze di programmazione: https://github.com/scrapinghub/portia


Va bene, grazie per la risposta, l'unico problema è che Python non è nel mio set di abilità. Esistono altri buoni linguaggi di programmazione che potrebbero svolgere le stesse attività? Lavoro principalmente con PHP e Javascript.
0x1ad2

Scusa per la confusione (ho menzionato il framework Python nella mia domanda), ma se Python è il modo migliore per farlo, potrei impararlo.
0x1ad2

Python rende scrapy molto facile. È anche facile da imparare. Il miglior raschietto che funziona bene al momento è raschiante. Hanno anche un'ottima documentazione.
Abhishek
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.