2014-06-05 10 views
8

Sto cercando di ottenere la fonte originale per una particolare pagina web.Posso ottenere la fonte originale della pagina (vs DOM corrente) con phantomjs/casperjs?

La pagina esegue alcuni script che modificano il DOM non appena viene caricato. Vorrei ottenere la fonte prima che uno script o un utente modifichi qualsiasi oggetto nel documento.

Con Chrome o Firefox (e probabilmente la maggior parte dei browser) posso neanche guardare il DOM (debug utilità F12) o di guardare fonte originale (tasto destro del mouse, visualizza sorgente). Quest'ultimo è ciò che voglio realizzare.

E 'possibile farlo con phantomjs/casperjs?

Prima di accedere alla pagina devo effettuare il login. Funziona perfettamente con casperjs. Se sfoglio la pagina e visualizzo i risultati, so che sono nella pagina giusta.

casper.thenOpen('http://'+customUrl, function(response) { 
    this.page.render('example.png'); // *** Renders correct page (current DOM) *** 
    console.log(this.page.content); // *** Gets current DOM *** 
    casper.download('view-source:'+customUrl, 'b.html', 'GET'); // *** Blank page *** 
    console.log(this.getHTML()); // *** Gets current DOM *** 
    this.debugPage(); // *** Gets current DOM *** 
    utils.dump(response); // *** No BODY *** 
    casper.download('http://'+customUrl, 'a.html', 'GET'); // *** Not logged in ?! *** 
}); 

Ho provato this.download(url, 'a.html') ma non sembra condividere lo stesso contesto, in quanto restituisce HTML come se non ero collegato, anche se corro con biscotti casperjs test.casper.js --cookies-file=cookies.txt.

Credo che dovrei continuare ad analizzare questa opzione.


Ho anche provato casper.open('view-source:url') invece di casper.open('http://url') ma sembra che non riconosce l'url da quando ottengo solo una pagina vuota.

Ho guardato la risposta HTTP non ricevuta dal server con un'utilità che ho e il corpo di questo messaggio (che è HTML) è quello di cui ho bisogno ma quando la pagina carica nel browser il DOM è già stato modificata.

ho provato:

casper.thenOpen('http://'+url, function(response) { 
    ... 
} 

Ma l'oggetto response contiene solo le intestazioni e alcune altre informazioni, ma non il corpo.


Ho provato anche con l'evento onResourceRequested.

L'idea è di interrompere il download di qualsiasi risorsa necessaria per una pagina Web specifica (il referer).

onResourceRequested: function(casperObj, requestData, networkRequest) { 
for (var i=0; i < requestData.headers.length; i++) { 
    var obj = requestData.headers[i]; 
    if (obj.name === "Referer" && obj.value === 'http://'+customUrl) { 
     networkRequest.abort(); 
     break; 
    } 
} 

Purtroppo lo script che modifica il DOM inizialmente sembra essere in linea la pagina HTML principale (o del presente codice non sta facendo quello che mi piace fare).


¿Qualche idea?

Ecco il codice completo:

phantom.casperTest = true; 
phantom.cookiesEnabled = true; 

var utils = require('utils'); 
var casper = require('casper').create({ 
    clientScripts: [], 
    pageSettings: { 
     loadImages: false, 
     loadPlugins: false, 
     javascriptEnabled: true, 
     webSecurityEnabled: false 
    }, 
    logLevel: "error", 
    verbose: true 
}); 

casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X)'); 

casper.start('http://www.xxxxxxx.xxx/login'); 

casper.waitForSelector('input#login', 
    function() { 
     this.evaluate(function(customLogin, customPassword) { 
      document.getElementById("login").value = customLogin; 
      document.getElementById("password").value = customPassword; 
      document.getElementById("button").click(); 
     }, { 
      "customLogin": customLogin, 
      "customPassword": customPassword 
     }); 
    }, 
    function() { 
     console.log('Can't login.'); 
    }, 
    15000 
); 

casper.waitForSelector('div#home', 
    function() { 
     console.log('Login successfull.'); 
    }, 
    function() { 
     console.log('Login failed.'); 
    }, 
    15000 
); 

casper.thenOpen('http://'+customUrl, function(response) { 
    this.page.render('example.png'); // *** Renders correct page (current DOM) *** 
    console.log(this.page.content); // *** Gets current DOM *** 
    casper.download('view-source:'+customUrl, 'b.html', 'GET'); // *** Blank page *** 
    console.log(this.getHTML()); // *** Gets current DOM *** 
    this.debugPage(); // *** Gets current DOM *** 
    utils.dump(response); // *** No BODY *** 
    casper.download('http://'+customUrl, 'a.html', 'GET'); // *** Not logged in ?! *** 
}); 

risposta

-1

Per quanto riguarda la docs è possibile utilizzare #debugPage() per ottenere il contenuto della pagina corrente.

casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X)'); 

casper.start('http://www.xxxxxxx.xxx/login'); 

casper.waitForSelector('input#login', ...); 

casper.then(function() { 
    this.debugHTML(); 
}); 

casper.run(); 

riguarda david

+0

OP vuole fonte del tutto invariato, ma debugPage stampa la pagina corrente. Questa non è una risposta. –

+0

Ho aggiornato la mia risposta per utilizzare #debugHTML() anziché #debugPage() –

+0

Che non funziona neanche. Non restituisce l'HTML originale. – supercoco

4

Hum, hai provato con alcuni eventi? Ad esempio:

casper.on('load.started', function(resource) { 
    casper.echo(casper.getPageContent()); 
}); 

Penso che non funzionerà, provalo lo stesso.

Il problema è: non è possibile farlo in un normale passaggio casperJS perché gli script nella pagina sono già stati eseguiti. Potrebbe funzionare se potessimo associare l'evento on-DOM-Ready o avere un evento casper specifico come quello. Problema: la pagina deve essere caricata per inviare alcuni js da Casper all'ambiente DOM. Non è possibile quindi vincolante (non vedo come). Penso che con il fantoccio possiamo raschiare DATA dopo l'evento load, quindi solo quando la pagina viene renderizzata.

Quindi, se non è possibile modificarlo con gli eventi e forse qualche ritardo, l'unica soluzione è bloccare gli script che modificano il DOM.

C'è ancora la possibilità phantomJS, lo si utilizza: Casper:

casper.pageSettings.javascriptEnabled = false; 

Il problema è che è necessario il js abilitati per ottenere indietro i dati, in modo che non può funzionare ...: p Sì commento inutile! :)

In caso contrario è necessario bloccare la risorsa/script ricercati che modificano il DOM utilizzando gli eventi.

Oppure è possibile utilizzare l'evento resource.received per analizzare i dati desiderati prima che vengano visualizzate le risorse specifiche per la modifica del DOM.

In realtà io non credo che sia possibile, perché se si crea un passo che tornare alcuni dati da pagina appaiano prima le risorse specifiche, la volta che si esegue il tuo passo, i ressources avranno carico. Sarebbe necessario bloccare le seguenti risorse mentre il passo sta raschiando i dati.

Non so come farlo, però, ma questi eventi potrebbe aiutare:

casper.on('resource.requested', function(request) { 
    console.log(" request " + request.url); 
}); 

casper.on('resource.received', function(resource) { 
    console.log(resource.url); 
}); 

casper.on('resource.error',function (request) { 
    this.echo('[res : id and url + error description] <-- ' + request.id + ' ' + request.url + ' ' + request.errorString); 
}); 

Vedi anche How do you Disable css in CasperJS?. La soluzione che funzionerebbe: identificate gli script e bloccateli. Ma se ne hai bisogno, beh, non lo so, è una bella domanda. Forse potremmo rimandare l'esecuzione di uno script specifico. Non credo che Casper e il fantasma lo permettano facilmente. L'unica opzione utile è abort(), dacci questa opzione: timeout("time -> ms")!

onResourceRequested

Ecco una domanda simile: Injecting script before other

+0

In realtà ho provato a utilizzare onResourceRequested (vedi nuova modifica). – supercoco

+0

E invece di interrompere, hai provato a recuperare l'HTML su una risorsa adeguata ricevuta? con 'var fs = require ('fs'); fs.write ("results.html", casper.getPageContent(), 'w'); ' – Fanch

2

Come Fanch ha sottolineato, a quanto pare non è possibile farlo. Se sei in grado di fare due richieste, allora diventa facile. Basta fare una richiesta con JavaScript abilitato e uno senza, in modo da poter raschiare l'origine della pagina e confrontarla.

casper 
    .then(function(){ 
     this.options.pageSettings.javascriptEnabled = false; 
    }) 
    .thenOpen(url, function(){ 
     this.echo("before JavaScript"); 
     this.echo(this.getHTML()); 
    }) 
    .then(function(){ 
     this.options.pageSettings.javascriptEnabled = true; 
    }) 
    .thenOpen(url, function(){ 
     this.echo("before JavaScript"); 
     this.echo(this.getHTML()); 
    }); 

È possibile modificare l'ordine in base alle proprie esigenze.Se sei già su una pagina che si desidera avere il markup originale, quindi è possibile utilizzare casper.getCurrentUrl() per ottenere l'URL corrente:

casper 
    .then(function(){ 
     // submit or whatever 
    }) 
    .thenOpen(url, function(){ 
     this.echo("after JavaScript"); 
     this.echo(this.getHTML()); 
     this.options.pageSettings.javascriptEnabled = false; 

     this.thenOpen(this.getCurrentUrl(), function(){ 
      this.echo("before JavaScript"); 
      this.echo(this.getHTML()); 
     }) 
    }); 
Problemi correlati