View Full Version : Estrazione dati da sito web - linguaggio
Ciao a tutti, ho bisogno di estrarre una serie di dati da un sito web ed eventualmente trasferirli in un file o in excel e vorrei un consiglio sul linguaggio di programmazione dal quale partire.
In secondo luogo leggendo altri thread qua e là ho visto che vi sono dei problemi se la pagina in questione è dinamica, potetreste darmi delle delucidazioni a ruguardo?
Grazie anticipatamente, Andrea.
puoi risolvere il tuo problema con un parse html se il sito e' scritto in html. puoi usare python, php, java, dipende da cosa conosci. parserizzare l'html e' una porta a rompimenti di balls enormi, questo se il tuo sito non offre i dati in json o xml.
per il fatto del sito dinamico non ci dovrebbero essere problemi. ovviamenti avrai dati diversi in base al istante in cui raccogli i dati dal sito.
ok, grazie per la risposta! se lo scrivo in php poi basta che apro il file .php che creo e da lì posso per esempio creare un bottone che una volta schiacciato esegue quello che devo fare giusto?
Hai invece qualche funzione da consigliarmi per questo scopo?
pabloski
13-11-2010, 11:47
sarebbe forse sensato chiederti che esperienza di programmazione hai :D
lo scraping non è certo qualcosa di banale e non è raro dover modificare il parser per ottenere buoni risultati
io ho sempre usato python + beautifulsoup che imho è il sistema più robusto per effettuare lo scraping di contenuti dal codice html
bè diciamo che di php ho una buobna conoscenza, l'ho usato per l'università per qualche same con apache e mysql... di python invece non so niente...
Usando php sapreste dirmi quindi da dove partire? Se è necessario usare qualche altro linguaggio o qualche funzione specifica?
Grazie :)
pabloski
13-11-2010, 12:25
il problema è che in php lo scraper te lo devi creare tu, mentre con python c'è già beautifulsoup che implementa il 99.99% di quello che ti serve
il discorso scraping è molto complesso, nel senso che non tutti i siti là fuori usano html scritto correttamente, moltissimi sono scritti male, con errori, omissioni, ecc....
un buon parser html implementa una serie di logiche euristiche che ti permettono di correggere il codice al volo e quindi di bypassare gli errori che i coder html mettono nei loro siti
in php sei praticamente da solo, in python hai beautifulsoup
chiaramente se devi fare il parsing di un singolo sito, allora ti vai a guardare il codice html e vedi se e dove ci sono errori e quindi riesci bene o male a creare un parser che funziona, ma se vuoi un parser per leggere vari siti html di cui non puoi ovviamente annotare tutti i difetti, devi appoggiarti a qualcosa di robusto
in teoria i migliori parser in assoluto sono quelli dei browser, tra cui quello di firefox è uno dei migliori.....ovviamente puoi interfacciarti con firefox, preferibilmente da python perchè ci sono dei wrapper appositi, oppure puoi interfacciarti a webkit, o se vuoi farla semplice usi beautifulsoup
bè diciamo che di php ho una buobna conoscenza, l'ho usato per l'università per qualche same con apache e mysql
Ma anche no allora.
il problema è che in php lo scraper te lo devi creare tu, mentre con python c'è già beautifulsoup che implementa il 99.99% di quello che ti serve
il discorso scraping è molto complesso, nel senso che non tutti i siti là fuori usano html scritto correttamente, moltissimi sono scritti male, con errori, omissioni, ecc....
un buon parser html implementa una serie di logiche euristiche che ti permettono di correggere il codice al volo e quindi di bypassare gli errori che i coder html mettono nei loro siti
in php sei praticamente da solo, in python hai beautifulsoup
chiaramente se devi fare il parsing di un singolo sito, allora ti vai a guardare il codice html e vedi se e dove ci sono errori e quindi riesci bene o male a creare un parser che funziona, ma se vuoi un parser per leggere vari siti html di cui non puoi ovviamente annotare tutti i difetti, devi appoggiarti a qualcosa di robusto
in teoria i migliori parser in assoluto sono quelli dei browser, tra cui quello di firefox è uno dei migliori.....ovviamente puoi interfacciarti con firefox, preferibilmente da python perchè ci sono dei wrapper appositi, oppure puoi interfacciarti a webkit, o se vuoi farla semplice usi beautifulsoup
Ok grazie, purtroppo di python non so niente, quindi vedo se riesco a fare qualcosa con php. Il sito dal quale preleverei i dati è sempre lo stesso, ho iniziato a vedere qualcosa di scraping, ho visto che c'è una libreria (cURL) che da quanto ho letto è molto utile. Spero che sbattendoci un po la testa riesca a fare qualcosa. Grazie cmq per le info :)
pabloski
13-11-2010, 15:35
curl permette di scaricare le pagine html, ma ovviamente non indicizza il DOM
del resto in php puoi benissimo usare file_get_contents ( se ovviamente nel php.ini hai abilitato la funzionalità di lettura di file remoti ) e quindi curl ti serve a ben poco
se si tratta sempre dello stesso sito allora puoi creare un banale scraper usando le espressioni regolari
cosa vuol dire che non indicizza il DOM?
Più che altro come faccio a selezionare una riga piuttosto che un'altra o dei determinati valori? Ci sono delle funzioni apposite? E' possibile inoltre spostarsi fra le pagine del sito in modo automatico?
Grazie ancora per le risposte.
banryu79
13-11-2010, 19:44
cosa vuol dire che non indicizza il DOM?.
vedi di qua (http://it.wikipedia.org/wiki/Document_Object_Model), oppure la più completa versione in lingua inglese, di la (http://en.wikipedia.org/wiki/Document_Object_Model).
Comunque credo che pabloski ti stia suggerendo accedere alla pagina html che ti interessa come ad uno stream dati: puoi (ad esempio, ma non solo, caricarla tutta in memoria e vederla come una unica stringa per poi) darla in pasto ad un matcher di regular expression al quale passerai dei pattern per estrarre i match che ti interessano.
Altrimenti analizzi linea per linea il contenuto per farci quello che ti pare.
ok, ho capito cos'è il DOM, ma il fatto che non lo poassa indicizzare cosa comporta in termini pratici?
pabloski
13-11-2010, 20:28
ok, ho capito cos'è il DOM, ma il fatto che non lo poassa indicizzare cosa comporta in termini pratici?
mi spiego con un esempio
prendiamo beautifulsoup che è un modulo python che serve proprio a creare il DOM partendo dal codice html....tu gli passi come parametro una stringa che contiene il codice html, lui internamente si crea una struttura di varia complessità che rappresenta il documento
ad esempio <html><body><h1>Ciao Pippo</h1><p>Io sono un cane</p></body></html>
il DOM si presenterà fatto così
html --> body --> h1 --> Ciao Pippo
--> p --> Io sono un cane
in pratica avrai un vettore che chiamiamo S per semplicità e avrai che S[0] contiene il contenuto di <html> e cioè il body e tutti gli elementi al suo interno
S[0][0] sarà un vettore di 2 elementi contenente h1 e p e i loro contenuti
S[0][0][0] sarà Ciao Pippo e S[0][0][1] sarà Io sono un cane
ovviamente il tutto associato a metadati che permettono di capire se il contenuto di un elemento dell'array è un elemento html, una semplice stringa di testo, un elemento cdata, ecc....
questo è il genere di struttura che si chiama DOM, poi ovviamente ogni libreria la gestisci fisicamente a modo suo ma concettualmente il DOM è una struttura contenente il codice html, sezionato in base ai vari tag, dov'è possibile navigare all'interno dei tag e quindi scoprire/leggere gli elementi contenuti all'interno dei vari tag, scendere ancora più sotto, fino ad arrivare agli elementi atomici che sono le stringhe di testo
per fare lo scraping di una pagina html ti serve qualcuno che sia in grado di creare una struttura del genere
in alternativa puoi semplicemente creare un matcher con le espressioni regolari, che però sarà un sistema che brutalmente estrae tutte le stringhe di testo ma non ti dà nessuna informazione riguardo lo status di quelle stringhe ( se erano contenute all'interno di tabelle, div, header, paragrafi, erano bold, em o che altro )
l'approccio basato su espressioni regolari funziona finchè il codice è corretto, ma guai ad avere un codice in cui un tag non si chiude oppure c'è un errore sintattico ( tipo <b al posto di <b> )....in questo caso il matcher comincerà a restituire stringhe di testo con dentro tag html e sarà un guaio grosso quanto una casa
in generale siccome è impossibile creare un parser degno di tale nome in maniera semplice, il mio suggerimento è di appoggiarsi ai parser di webkit o gecko, perchè si tratta di software molto sofisticato, capace di generare il DOM a partire da html malridotto
grazie mille per la spiegazione esauriente. Ora provo a vedere se riesco a fare qualcosa in php, magari per quello che devo fare non c'è bisogno di cose troppo complesse, in tal caso invece proverò o con python o come dici tu usando quei parser.
Grazie ancora :)
Scusate il doppio post, sto facendo qualche prova con php, usando funzioni semplici come la file get content. Purtroppo quando uso questa funzione inserendo l'url del sito desiderato ottengo quest'eerore:
[function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error in C:\xampp\htdocs\prova2.php on line 7
forse è dovuto al fatto che l'url in questione non termina con una pagina .php o .html o che fa uso i script? perchè ho visto che nel sorgente della pagina ve ne sono...
pabloski
14-11-2010, 14:43
Quel messaggio ti dice semplicemente che il server non è in grado di elaborare la richiesta. Il problema non è dello script ma del server.
quindi vuol dire che da quel sito non è possibile in nessun modo estrarre dati dal codice sorgente?
pabloski
14-11-2010, 18:10
quindi vuol dire che da quel sito non è possibile in nessun modo estrarre dati dal codice sorgente?
No questo è oggettivamente impossibile. Semplicemente richiedere quell'url causa un errore. Se accedi allo stesso url dal browser che succede?
l'url dal browser funziona, è da lì che l'ho preso. Cosa può essere allora?
pabloski
14-11-2010, 21:50
l'url dal browser funziona, è da lì che l'ho preso. Cosa può essere allora?
Potrebbe essere che analizza l'useragent.
e quindi come posso fare per ovviare a questo problema?
pabloski
15-11-2010, 10:27
prova con curl, altrimenti devi analizzare il problema, capire cos'è che non va
banryu79
15-11-2010, 10:59
Se l'utente Gimmy2 ha come browser firefox potrebbe installare il componente aggiuntivo "Live HTTP Headers" e sbirciare gli header di risposta del server.
grazie per le risposte. :) Con curl riesco a creare il file xml di quella pagina, ma ahimè le informazioni che cerco non si trovano lì ma sono presenti solo nel sorgente html. E purtroppo usando la fopen per leggere il codice html mi dà quell'errore, quindi come faccio?
Il componente di firefox sarebbe utile, ma cmq avrei il problema dell'estrazione e dell'elaborazione dei dati.
EDIT: sono riuscito a far funzionare la fopen e la file get content aggiungendo ini_set ('user_agent', $_SERVER['HTTP_USER_AGENT']); prima dell'istruzione. Ora dovrei riuscire ad estrarre i dati di mio interesse dal file creato giusto?
EDIT 2: Non riesco a capire. Nel sorgente html del sito sono presenti i dati he mi interessano, ma nel sorgente html che estraggo tramite la fopen no. Possibile che quei dati siano generati mediante javascript? In quel caso come faccio a prelevare quei dati??
Si chiama "web scraping" e se ne hai bisogno potresti anche considerare l'idea di prendere questo in pdf per capire un pò tutte le metodologie: http://www.phparch.com/books/phparchitects-guide-to-web-scraping-with-php/
Grazie per il libro, ora lo vedo. Più che altro sto ancora pensando al problema di base: con curl ottengo l'xml del sito ma non vi sono le parti che mi interessano, con la fopen ottengo il codice sorgente ma è diverso da quello originale del sito perchè (suppongo) mancano gli script che generano i dati che mi interessano. Come posso fare? Forse con curl si può ottenere qualcosa di più specifico?
Grazie per il libro, ora lo vedo. Più che altro sto ancora pensando al problema di base: con curl ottengo l'xml del sito ma non vi sono le parti che mi interessano, con la fopen ottengo il codice sorgente ma è diverso da quello originale del sito perchè (suppongo) mancano gli script che generano i dati che mi interessano. Come posso fare? Forse con curl si può ottenere qualcosa di più specifico?
Mh non ho capito o.o
pabloski
15-11-2010, 17:33
Grazie per il libro, ora lo vedo. Più che altro sto ancora pensando al problema di base: con curl ottengo l'xml del sito ma non vi sono le parti che mi interessano, con la fopen ottengo il codice sorgente ma è diverso da quello originale del sito perchè (suppongo) mancano gli script che generano i dati che mi interessano. Come posso fare? Forse con curl si può ottenere qualcosa di più specifico?
what? ma come diavolo è fatto questo sito?
inviando una richiesta GET al server riceverai ovviamente gli elementi statici e cioè l'html di cui è composta la pagina
è ovvio che se quella pagina ingloba script esterni, devono parsare l'html, estrarre i path di quegli script e scaricare pure quelli....se la pagina poi è costruita dinamicamente tramite ajax, allora devi simulare un vero e proprio browser che sia in grado di eseguire il javascript e quindi renderizzare correttamente la pagina
In pratica: se apro il codice sorgente del sito in questione dal browser riesco a vedere i dati che mi interessano, però se apro il codice sorgente in php tramite fopen o file get content vedo solo il codice html e non i dati che mi interessano, forse perchè questi ultimi sono generati da script e quindi quando copio il sorgente sul mio pc non vengono trasferiti. Stesso discorso con curl: riesco a generare il file xml della pagina ma al suo interno non vi sono i dati che mi interessano, che invece sono presenti nel codice sorgente della pagina visibile dal browser.
what? ma come diavolo è fatto questo sito?
inviando una richiesta GET al server riceverai ovviamente gli elementi statici e cioè l'html di cui è composta la pagina
è ovvio che se quella pagina ingloba script esterni, devono parsare l'html, estrarre i path di quegli script e scaricare pure quelli....se la pagina poi è costruita dinamicamente tramite ajax, allora devi simulare un vero e proprio browser che sia in grado di eseguire il javascript e quindi renderizzare correttamente la pagina
mmm ok, ma come scarico gli script esterni e come faccio a capire se è costruita tramite ajax?
Cmq in php provando ad aprirla con fopen e succcessivamente a stamparla, nel riquadro centrale della pagina (dove ci sono le info che mi interessano) vi è un'immagine di caricamento che continua all'infinito...
Grazie mille per le risposte.
pabloski
15-11-2010, 18:06
mmm ok, ma come scarico gli script esterni e come faccio a capire se è costruita tramite ajax?
Cmq in php provando ad aprirla con fopen e succcessivamente a stamparla, nel riquadro centrale della pagina (dove ci sono le info che mi interessano) vi è un'immagine di caricamento che continua all'infinito...
Grazie mille per le risposte.
ovviamente devi guardarti l'eventuale codice javascript presente in quell'html e capire cosa fa
il browser ovviamente esegue i javascript e quindi può fare cose che semplicemente il codice html non puoi fare
ovviamente devi guardarti l'eventuale codice javascript presente in quell'html e capire cosa fa
il browser ovviamente esegue i javascript e quindi può fare cose che semplicemente il codice html non puoi fare
mmm... quindi vuol dire che nel file php che creo devo inserire codice javascript? Cioè una volta che capisco dal sorgente html cosa fa il codice javascript come mi comporto?
pabloski
15-11-2010, 20:33
mmm... quindi vuol dire che nel file php che creo devo inserire codice javascript? Cioè una volta che capisco dal sorgente html cosa fa il codice javascript come mi comporto?
mi sa che stai facendo un bel pò di confusione tra lo script di scraping e gli eventuali script server-side del sito da scrapare
quello che devi fare tu è creare uno scraper che sia in grado di eseguire codice javascript
ok, ma nello scraper che creo io in php come faccio a fargli leggere anche gli script in javascript che esegue il server e che copiando il codice html della pagina non vedo?
banryu79
15-11-2010, 22:46
ok, ma nello scraper che creo io in php come faccio a fargli leggere anche gli script in javascript che esegue il server e che copiando il codice html della pagina non vedo?
La sparo: non è che nell'html della pagina che ti arriva come risposta da qualche parte c'è un riferimento/url al/ai file di script del server da eseguire?
La sparo: non è che nell'html della pagina che ti arriva come risposta da qualche parte c'è un riferimento/url al/ai file di script del server da eseguire?
Credo di si, nel senso nel file html che creo tramite php ci sono dei link...
Quindi li dovrei eseguire per avere il codice sorgente originale? In tale come devo fare?
Ho installato firebug ed entrando nella pagina in questione nel codice sorgente html sono presenti i dati che mi interessano. Inoltre ho notato che sono presenti più funzioni javascript che generano questi dati...
Quindi il domandone è: esiste un modo in php o in qualche altro linguaggio che permette di eseguire tali script in modo da avere il codice sorgente completo di tutti i dati??
pabloski
16-11-2010, 17:08
Ho installato firebug ed entrando nella pagina in questione nel codice sorgente html sono presenti i dati che mi interessano. Inoltre ho notato che sono presenti più funzioni javascript che generano questi dati...
Quindi il domandone è: esiste un modo in php o in qualche altro linguaggio che permette di eseguire tali script in modo da avere il codice sorgente completo di tutti i dati??
il modo c'è ed è ovviamente di creare un interprete javascript....si può fare? ovviamente no, ti occorrerebbero mesi
è questo il motivo per cui ho detto che devi usare i parser dei browser e sfruttare i loro engine per fargli fare tutto il lavoro
non è pensabile di creare un browser con tanto di capacità di esecuzione del javascript solo per fare lo scraping
Grazie per la risposta, ora ho capito la situazione. per quanto riguarda gli scrpaer dei browser ne coosci qualuno? L'add-on "Firebug" di firefox è uno di questi? E cmq utilizzando questi scraper dal browser come faccio trasferire i dati in mod automatico in un file epr esempio? Fanno tutto loro in modo automatico o devo scrivere cmq del codice?
pabloski
16-11-2010, 17:35
Grazie per la risposta, ora ho capito la situazione. per quanto riguarda gli scrpaer dei browser ne coosci qualuno? L'add-on "Firebug" di firefox è uno di questi? E cmq utilizzando questi scraper dal browser come faccio trasferire i dati in mod automatico in un file epr esempio? Fanno tutto loro in modo automatico o devo scrivere cmq del codice?
no veramente che io sappia non esistono scraper di browser, esistono scraper che usano i motori dei browser ma per ovvie ragioni sono usati dagli esperti del SEO e della generazione automatica di contenuti e di certo non li trovi aggratis sulla rete
firebug è un'estensione per il debugging non è uno scraper
lo scraper devi costruirtelo tu utilizzando però i motori dei browser per fare il lavoro complicato
ad esempio puoi usare jxbrowser per java o pyxpcom per python che sono dei binding per mozilla gecko, ma ovviamente devi comunque scrivere un programma
banryu79
17-11-2010, 08:47
il modo c'è ed è ovviamente di creare un interprete javascript....si può fare? ovviamente no, ti occorrerebbero mesi
è questo il motivo per cui ho detto che devi usare i parser dei browser e sfruttare i loro engine per fargli fare tutto il lavoro
non è pensabile di creare un browser con tanto di capacità di esecuzione del javascript solo per fare lo scraping
La sparo di nuovo (e due :D) perchè ho solo un'esperienza piuttosto banale di scraping, ma nel caso usasse Java non potrebbe cavarsela appoggiandosi alle scripting API? (javax.script)
no veramente che io sappia non esistono scraper di browser, esistono scraper che usano i motori dei browser ma per ovvie ragioni sono usati dagli esperti del SEO e della generazione automatica di contenuti e di certo non li trovi aggratis sulla rete
firebug è un'estensione per il debugging non è uno scraper
lo scraper devi costruirtelo tu utilizzando però i motori dei browser per fare il lavoro complicato
ad esempio puoi usare jxbrowser per java o pyxpcom per python che sono dei binding per mozilla gecko, ma ovviamente devi comunque scrivere un programma
ok, in questo caso dovrei cmq scrivere del codice in python o java giusto? E non credo neanche che sia una cosa semplice immagino...!
La sparo di nuovo (e due ) perchè ho solo un'esperienza piuttosto banale di scraping, ma nel caso usasse Java non potrebbe cavarsela appoggiandosi alle scripting API? (javax.script)
attendo una risposta anch'io :D
EDIT: In rete ho trovato questo: http://simplehtmldom.sourceforge.net/ , è scritto in php e sembra ben fatto, non ho ancora letto tutte le funzioni che supporta, dite che è possibile che possa eseguire gli script del sito in modo da fornire il codice html completo?
pabloski
17-11-2010, 14:54
La sparo di nuovo (e due :D) perchè ho solo un'esperienza piuttosto banale di scraping, ma nel caso usasse Java non potrebbe cavarsela appoggiandosi alle scripting API? (javax.script)
wow non lo conoscevo questo package.....in pratica è un wrapper universale per vari linguaggi di scripting e in combinazione con Rhino fa un perfetto interprete javascript
hehe è arrivato il momento di giocherellare un pò con javascript :D
ok, in questo caso dovrei cmq scrivere del codice in python o java giusto? E non credo neanche che sia una cosa semplice immagino...!
si, non è una cosa banale ma nemmeno impossibile.....rimane il problema che questo genere di software non lo trovi su internet
EDIT: In rete ho trovato questo: http://simplehtmldom.sourceforge.net/ , è scritto in php e sembra ben fatto, non ho ancora letto tutte le funzioni che supporta, dite che è possibile che possa eseguire gli script del sito in modo da fornire il codice html completo?
è l'equivalente php di beautifulsoup, ma rimane il problema del javascript
banryu79
17-11-2010, 15:17
wow non lo conoscevo questo package.....in pratica è un wrapper universale per vari linguaggi di scripting e in combinazione con Rhino fa un perfetto interprete javascript
hehe è arrivato il momento di giocherellare un pò con javascript :D
Sì, quel package è stato introdotto nel JDK 6; qui c'è un articolo che può essere utile per mouvere i primi passi e valutare se l'approccio è valido per il problema dell'utente:
- http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting/
(e io direi di sì: avendo l'url degli script da eseguire e' possibile tramite un inputstream reader passare il tutto all'interprete incluso nel prezzo)
pabloski
17-11-2010, 16:06
Sì, quel package è stato introdotto nel JDK 6; qui c'è un articolo che può essere utile per mouvere i primi passi e valutare se l'approccio è valido per il problema dell'utente:
- http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting/
(e io direi di sì: avendo l'url degli script da eseguire e' possibile tramite un inputstream reader passare il tutto all'interprete incluso nel prezzo)
eh poi i fan delle finestre ci chiedono perchè preferiamo java :D
banryu79
17-11-2010, 16:38
eh poi i fan delle finestre ci chiedono perchè preferiamo java :D
"Zitto e nuota" :O (cit.)
ok ho capito :) grazie ad entrambi per le varie delucidazioni sull'argomento :)
In definita per risolvere il problema dovrei scrivere un programma in java usando quella libreria.
Sfortunatamente non so programmare in java quindi l'unica cosa che posso fare è rimboccarmi le maniche ed impararlo almeno il necessario per quel che mi serve!
Grazie ancora per i consigli e per le dritte :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.