2011-09-07 19 views
8

Ho bisogno di fare un po 'di scraping web. Dopo aver giocato con diversi framework di testing web, dei quali più troppo lento (Selenium) o troppo buggy per i miei bisogni (env.js), ho deciso che zombie.js sembra molto promettente, poiché utilizza un solido set di librerie per l'analisi HTML e manipolazione DOM. Tuttavia, mi sembra come se non ha nemmeno supporta il codice di base basata su eventi JavaScript come nella seguente pagina web:Problemi con scraping del sito web utilizzando zombie.js

<html> 
    <head> 
    <title>test</title> 
    <script type="text/javascript"> 

     console.log("test script executing..."); 
     console.log("registering callback for event DOMContentLoaded on " + document); 

     document.addEventListener('DOMContentLoaded', function(){ 
     console.log("DOMContentLoaded triggered"); 
     }, false); 

     function loaded() { 
     console.log("onload triggered"); 
     } 

    </script> 
    </head> 

    <body onload="loaded();"> 
    <h1>Test</h1> 
    </body> 
</html> 

Ho quindi deciso di attivare quegli eventi manualmente in questo modo:

zombie = require("zombie"); 

zombie.visit("http://localhost:4567/", { debug: true }, function (err, browser, status) { 

    doc = browser.document; 
    console.log("firing DOMContentLoaded on " + doc); 
    browser.fire("DOMContentLoaded", doc, function (err, browser, status) { 

    body = browser.querySelector("body"); 
    console.log("firing load on " + body); 
    browser.fire("load", body, function (err, browser, status) { 

     console.log(browser.html()); 

    }); 
    }); 

}); 

Che funziona per questa particolare pagina di test. Il mio problema è più generale, tuttavia: voglio essere in grado di grattare siti più complessi basati su AJAX come un elenco di amici su Facebook (qualcosa come http://www.facebook.com/profile.php?id=100000028174850&sk=friends&v=friends). Non è un problema accedere al sito usando zombie, ma alcuni contenuti come quelli sembrano caricati completamente dinamicamente usando AJAX, e non so come attivare i gestori di eventi che avviano il caricamento.

Ci sono diverse domande che ho per quanto riguarda questo problema:

  • Ha qualcuno già implementato un raschietto simile complesso senza utilizzare un browser remoto-controllo soluzione come selenio?
  • Esiste qualche riferimento sul processo di caricamento di una pagina complessa basata su Javascript?
  • Qualcuno può fornire consigli su come eseguire il debug di un browser reale per vedere cosa potrebbe essere necessario eseguire per attivare i gestori di eventi di Facebook?
  • Altre idee su questo argomento?

Ancora una volta, per favore non puntare a soluzioni che riguardano il controllo di un browser reale come il Selenium, come so di questi. Ciò che è comunque benvenuto sono i suggerimenti per un vero renderer in-memory come WebKit accessibile dal linguaggio di scripting di Ruby, ma preferibilmente con la possibilità di impostare cookie e preferibilmente caricare anche HTML non elaborato invece di attivare richieste HTTP reali.

+0

Stai cercando un framework di test javascript o uno strumento di estrazione dei dati web? Se stai cercando uno strumento per la raschiatura dei graffi, è possibile analizzare la maggior parte dei siti senza eseguire Javascript, anche quelli pesanti AJAX. – chesles

+1

La domanda riguarda il web scraping. Hai ragione, spesso è effettivamente possibile farlo senza eseguire Js, ad es. emettendo richieste REST manualmente. Nel caso di Facebook, raschiare la versione mobile del sito è del tutto possibile utilizzando solo l'analisi HTTP e HTML. Ma sono interessato a una soluzione generica che comprenda Javascript e non richieda una reale istanza del browser. Questo sembra essere possibile, come mostrano env.Js e zombie.Js, ma sembra essere un problema di trucchi. –

risposta

12

Ai fini dell'estrazione dei dati, l'esecuzione manuale di un "browser senza testa" e l'attivazione manuale degli eventi javascript non sarà la cosa più facile da fare. Sebbene non sia impossibile, ci sono modi più semplici per farlo.

La maggior parte dei siti, anche quelli pesanti AJAX, possono essere scaricati senza eseguire una singola riga del loro codice Javascript. Infatti, è che di solito è più facile che cercare di capire il codice Javascript di un sito, che è spesso offuscato, minificato e difficile da eseguire il debug. Se hai una solida conoscenza di HTTP capirai perché: (quasi) tutte le interazioni con il server sono codificate come richieste HTTP, quindi se sono avviate da Javascript, o dall'utente che fa clic su un link, o codice personalizzato in un programma bot, non c'è differenza per il server. (Dico quasi perché quando vengono coinvolti Flash o applet non si sa quali dati stanno volando, possono essere specifici dell'applicazione, ma qualsiasi cosa fatta in Javascript andrà su HTTP.)

Detto questo, è possibile imitare un utente su qualsiasi sito Web utilizzando un software personalizzato. Per prima cosa devi essere in grado di vedere le richieste HTTP non inviate al server. È possibile utilizzare un server proxy per registrare le richieste effettuate da un browser reale sul sito Web di destinazione. Ci sono molti, molti strumenti che puoi usare per questo: Charles o Fiddler sono a portata di mano, la maggior parte dedicata allo screen-scraper tools ha un proxy di base integrato, l'estensione Firebug per Firefox e Chrome hanno strumenti simili per visualizzare le richieste AJAX ... ti viene l'idea .

Una volta visualizzate le richieste HTTP effettuate a seguito di una determinata azione sul sito Web, è facile scrivere un programma per simulare tali richieste; basta inviare le stesse richieste al server e tratterà il tuo programma proprio come un browser in cui è stata eseguita un'azione particolare.

Esistono diverse librerie per lingue diverse che offrono funzionalità diverse. Per rubino, ho visto un sacco di persone che usano mechanize for ruby.

Se l'estrazione dei dati è il tuo unico obiettivo, sarai quasi sempre in grado di ottenere ciò di cui hai bisogno imitando le richieste HTTP in questo modo. Nessun Javascript richiesto.

Nota - Dal momento che lei ha citato Facebook, vorrei ricordare che la raschiatura Facebook specificamente può essere estremamente difficile (anche se non impossibile), perché Facebook ha misure in atto per rilevare l'accesso automatizzato (che utilizzano più di un semplice captcha); disabiliteranno un account se vedranno attività sospette provenienti da esso. Dopotutto, è contro il loro terms of service (sezione 3.2).

+1

Grazie per aver formulato questa risposta sofisticata alla domanda. Uso già Firebug e Fiddler2 per monitorare il traffico HTTP da e verso i server web, che tuttavia non è molto utile se si utilizza un tema di comunicazione difficile da applicare, come fatto da molti siti di social networking. Ma anche se è possibile utilizzare l'interfaccia di basso livello per parlare con un server Web ed estrarre informazioni, ciò richiederà un costante aggiustamento del raschiatore, che può richiedere molto tempo. Env.js (che ho quasi imparato a funzionare come voglio) mostra che è in effetti possibile simulare un browser reale a livello di codice. –

+0

È vero, Facebook e altri siti cercano di renderlo il più difficile possibile per voi di raschiare i loro siti; preferiscono che tu usi le loro API in modo da poter controllare meglio l'accesso al tuo programma, e quindi proteggere meglio la privacy dei loro utenti. – chesles

+0

Ancora, emulare un utente di navigazione con uno strumento come il selenio sembra funzionare senza problemi (tranne che per lentezza), non ho incontrato ostacoli se non per l'uso esteso del contenuto dinamico. Anche OAuth non è affatto protetto dall'accesso automatizzato, l'autenticazione può essere programmata senza problemi e non richiede nemmeno Javascript per funzionare. –