Toma el contenido de los recursos en CasperJS o PhantomJS

Veo que CasperJS tiene una función de “descarga” y una callback “en recursos recibidos”, pero no veo el contenido de un recurso en la callback, y no quiero descargar el recurso al sistema de archivos.

Quiero tomar los contenidos del recurso para poder hacer algo con él en mi script. ¿Es esto posible con CasperJS o PhantomJS?

Este problema ha estado en mi camino durante los últimos días. La solución de proxy no estaba muy limpia en mi entorno, así que descubrí dónde el núcleo de QTNetworking de phantomjs ponía los recursos cuando los almacenaba.

Para resumir, aquí está mi esencia. Necesita los archivos cache.js y mimetype.js: https://gist.github.com/bshamric/4717583

//for this to work, you have to call phantomjs with the cache enabled: //usage: phantomjs --disk-cache=true test.js var page = require('webpage').create(); var fs = require('fs'); var cache = require('./cache'); var mimetype = require('./mimetype'); //this is the path that QTNetwork classes uses for caching files for it's http client //the path should be the one that has 16 folders labeled 0,1,2,3,...,F cache.cachePath = '/Users/brandon/Library/Caches/Ofi Labs/PhantomJS/data7/'; var url = 'http://google.com'; page.viewportSize = { width: 1300, height: 768 }; //when the resource is received, go ahead and include a reference to it in the cache object page.onResourceReceived = function(response) { //I only cache images, but you can change this if(response.contentType.indexOf('image') >= 0) { cache.includeResource(response); } }; //when the page is done loading, go through each cachedResource and do something with it, //I'm just saving them to a file page.onLoadFinished = function(status) { for(index in cache.cachedResources) { var file = cache.cachedResources[index].cacheFileNoPath; var ext = mimetype.ext[cache.cachedResources[index].mimetype]; var finalFile = file.replace("."+cache.cacheExtension,"."+ext); fs.write('saved/'+finalFile,cache.cachedResources[index].getContents(),'b'); } }; page.open(url, function () { page.render('saved/google.pdf'); phantom.exit(); }); 

Luego, cuando llamas a phantomjs, solo asegúrate de que la caché esté habilitada:

phantomjs –disk-cache = true test.js

Algunas notas: escribí esto con el propósito de obtener las imágenes en una página sin usar el proxy o tomar una instantánea de baja resolución. QT usa compresión en ciertos recursos de archivos de texto y tendrá que lidiar con la descompresión si usa esto para archivos de texto. Además, ejecuté una prueba rápida para extraer recursos html y no analizó los encabezados http del resultado. Pero, esto es útil para mí, espero que alguien más lo encuentre así, modifíquelo si tiene problemas con un tipo de contenido específico.

Descubrí que hasta que el phantomjs madure un poco, según el número 158 http://code.google.com/p/phantomjs/issues/detail?id=158, esto es un dolor de cabeza para ellos.

Entonces, ¿quieres hacerlo de todos modos? He optado por ir un poco más alto para lograr esto y he tomado PyMiProxy en https://github.com/allfro/pymiproxy , lo descargué, lo instalé, lo configuré, tomé su código de ejemplo y lo hice en proxy.py

 from miproxy.proxy import RequestInterceptorPlugin, ResponseInterceptorPlugin, AsyncMitmProxy from mimetools import Message from StringIO import StringIO class DebugInterceptor(RequestInterceptorPlugin, ResponseInterceptorPlugin): def do_request(self, data): data = data.replace('Accept-Encoding: gzip\r\n', 'Accept-Encoding:\r\n', 1); return data def do_response(self, data): #print '<< %s' % repr(data[:100]) request_line, headers_alone = data.split('\r\n', 1) headers = Message(StringIO(headers_alone)) print "Content type: %s" %(headers['content-type']) if headers['content-type'] == 'text/x-comma-separated-values': f = open('data.csv', 'w') f.write(data) print '' return data if __name__ == '__main__': proxy = AsyncMitmProxy() proxy.register_interceptor(DebugInterceptor) try: proxy.serve_forever() except KeyboardInterrupt: proxy.server_close() 

Luego lo enciendo

 python proxy.py 

A continuación, ejecuto phantomjs con el proxy especificado ...

 phantomjs --ignore-ssl-errors=yes --cookies-file=cookies.txt --proxy=127.0.0.1:8080 --web-security=no myfile.js 

Es posible que desee activar su seguridad o tal, era innecesario para mí en la actualidad, ya que estoy raspando una sola fuente. Ahora debería ver un montón de texto que fluye a través de la consola de proxy y si aterriza en algo con el tipo mime de "text-x-comma-separated-values" lo guardará como data.csv. Esto también guardará todos los encabezados y todo, pero si has llegado hasta aquí, estoy seguro de que puedes descubrir cómo quitarlos.

Otro detalle, he descubierto que he tenido que deshabilitar la encoding gzip, podría usar zlib y descomprimir datos en gzip desde mi propio servidor web apache, pero si sale de IIS o tal, la descompresión obtendrá errores y yo ' No estoy seguro de esa parte de eso.

¿Entonces mi compañía eléctrica no me ofrecerá una API? ¡Multa! ¡Lo hacemos de la manera difícil!

No me di cuenta de que podía tomar la fuente del documento objeto de esta manera:

 casper.start(url, function() { var js = this.evaluate(function() { return document; }); this.echo(js.all[0].outerHTML); }); 

Más información aquí .

Puede usar Casper.debugHTML() para imprimir los contenidos de un recurso HTML:

 var casper = require('casper').create(); casper.start('http://google.com/', function() { this.debugHTML(); }); casper.run(); 

También puede almacenar los contenidos HTML en una var usando casper.getPageContent() : http://casperjs.org/api.html#casper.getPageContent (disponible en el último maestro)

    Intereting Posts