20

我看到 CasperJS 有一个“下载”功能和一个“收到资源”回调,但我没有在回调中看到资源的内容,我不想将资源下载到文件系统。

我想获取资源的内容,以便我可以在我的脚本中使用它。CasperJS 或 PhantomJS 有可能吗?

4

4 回答 4

17

在过去的几天里,这个问题一直困扰着我。代理解决方案在我的环境中不是很干净,所以我发现 phantomjs 的 QTNetworking 核心在缓存资源时将资源放在哪里。

长话短说,这是我的要点。您需要 cache.js 和 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();
});

然后当你调用 phantomjs 时,只需确保启用了缓存:

phantomjs --disk-cache=true test.js

一些注意事项:我写这篇文章的目的是在不使用代理或拍摄低分辨率快照的情况下获取页面上的图像。QT 对某些文本文件资源使用压缩,如果您将其用于文本文件,您将不得不处理解压缩。此外,我运行了一个快速测试以提取 html 资源,但它没有从结果中解析出 http 标头。但是,这对我很有用,希望其他人会发现它,如果您对特定内容类型有问题,请修改它。

于 2013-02-05T21:14:56.843 回答
16

我发现直到 phantomjs 成熟一点,根据问题 158 http://code.google.com/p/phantomjs/issues/detail?id=158这对他们来说有点头疼。

所以你还是想做吗?我选择了更高一点来完成此任务,并在https://github.com/allfro/pymiproxy上获取了 PyMiProxy ,下载、安装、设置、获取他们的示例代码并在 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()

然后我点燃它

python proxy.py

接下来我使用指定的代理执行 phantomjs...

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

您可能想要打开您的安全性等,这对我来说是不必要的,因为我只抓取一个来源。您现在应该看到一堆文本流经您的代理控制台,如果它落在 mime 类型为“text/x-comma-separated-values”的东西上,它将保存为 data.csv。这也将保存所有标题和所有内容,但是如果您已经走到这一步,我相信您可以弄清楚如何将它们弹出。

另一个细节,我发现我必须禁用 gzip 编码,我可以使用 zlib 并从我自己的 apache 网络服务器解压缩 gzip 中的数据,但如果它来自 IIS 或这样的解压缩会出错,我'我不确定那部分。

所以我的电力公司不会为我提供 API?美好的!我们努力做到这一点!

于 2012-08-24T21:34:46.513 回答
2

没有意识到我可以像这样从文档对象中获取源代码:

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

更多信息在这里

于 2012-10-24T17:07:59.373 回答
1

您可以使用Casper.debugHTML()打印出 HTML 资源的内容:

var casper = require('casper').create();

casper.start('http://google.com/', function() {
    this.debugHTML();
});

casper.run();

您还可以使用以下方法将 HTML 内容存储在 var 中casper.getPageContent()http ://casperjs.org/api.html#casper.getPageContent (在最新的 master 中可用)

于 2012-07-18T05:05:58.113 回答