如何在AWS Lambda上部署phantomjs节点应用程序?

我把一个小的Lambda函数放在一起,使用SpookyJS,CasperJS和PhantomJS工具链来抓取一个网站来进行无头浏览。 这个任务很简单,几个月前在Lambda工作。 我最近不得不改变一些东西,想再次在这个项目上工作,但是开始新鲜起来,很难让Lambda在没有任何错误的情况下运行。 我的问题是如何在Lambda中运行phantomjs

我正在运行的示例代码是:

spooky.start('http://en.wikipedia.org/wiki/Spooky_the_Tuff_Little_Ghost'); spooky.then(function () { this.emit('hello', 'Hello, from ' + this.evaluate(function () { return document.title; })); }); spooky.run(); 

我在Lambda中遇到的错误是:

 { [Error: Child terminated with non-zero exit code 1] details: { code: 1, signal: null } } 

我遵循了各种程序,以确保一切都能在Lambda上运行。 以下是我尝试诊断的一长串列表:

  1. 使用node index.js在本地运行并确认它正在工作
  2. 将package.json和jsfile upload到Amazon Linux EC2实例以进行编译,build议用于npm安装调用,并在此处介绍
  3. 在ec2实例上运行npm install ,并再次运行node index.js以确保输出正确
  4. 压缩一切,并使用cli部署到AWS

我的package.json是:

 { "name": "lambda-spooky-test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "casperjs": "^1.1.3", "phantomjs-prebuilt": "^2.1.10", "spooky": "^0.2.5" } } 

我也尝试了以下(大多数也在本地工作,并在AWS EC2实例上,但在Lambda上出现相同的错误:

  1. 尝试非幻影版本的幻影
  2. 使用process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'] + ':' + process.env['LAMBDA_TASK_ROOT'] + '/node_modules/.bin'; console.log( 'PATH: ' + process.env.PATH );确保casperjs和phantomjs的可访问性process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'] + ':' + process.env['LAMBDA_TASK_ROOT'] + '/node_modules/.bin'; console.log( 'PATH: ' + process.env.PATH ); process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'] + ':' + process.env['LAMBDA_TASK_ROOT'] + '/node_modules/.bin'; console.log( 'PATH: ' + process.env.PATH );
  3. 通过包装child_process的.spawn()调用来检查spawn调用,并得到以下结果:

     { '0': 'casperjs', '1': [ '/var/task/node_modules/spooky/lib/bootstrap.js', '--transport=http', '--command=casperjs', '--port=8081', '--spooky_lib=/var/task/node_modules/spooky/lib/../', '--spawnOptions=[object Object]' ], '2': {} } 
  4. 直接调用.exec('casperjs').exec('phantomjs --version') ,确认它在本地和EC2上工作,但在Lambda中得到以下错误。 命令:

     `require('child_process').exec('casperjs', (error, stdout, stderr) => { if (error) { console.error('error: ' + error); } console.log('out: ' + stdout); console.log('err: ' + stderr); }); 

两者的结果如下:

 err: Error: Command failed: /bin/sh -c casperjs module.js:327 throw err; ^ Error: Cannot find module '/var/task/node_modules/lib/phantomjs' at Function.Module._resolveFilename (module.js:325:15) at Function.Module._load (module.js:276:25) at Module.require (module.js:353:17) at require (internal/module.js:12:17) at Object.<anonymous> (/var/task/node_modules/.bin/phantomjs:16:15) at Module._compile (module.js:409:26) at Object.Module._extensions..js (module.js:416:10) at Module.load (module.js:343:32) at Function.Module._load (module.js:300:12) at Function.Module.runMain (module.js:441:10) 2016-08-07T15:36:37.349Z b9a1b509-5cb4-11e6-ae82-256a0a2817b9 sout: 2016-08-07T15:36:37.349Z b9a1b509-5cb4-11e6-ae82-256a0a2817b9 serr: module.js:327 throw err; ^ Error: Cannot find module '/var/task/node_modules/lib/phantomjs' at Function.Module._resolveFilename (module.js:325:15) at Function.Module._load (module.js:276:25) at Module.require (module.js:353:17) at require (internal/module.js:12:17) at Object.<anonymous> (/var/task/node_modules/.bin/phantomjs:16:15) at Module._compile (module.js:409:26) at Object.Module._extensions..js (module.js:416:10) at Module.load (module.js:343:32) at Function.Module._load (module.js:300:12) at Function.Module.runMain (module.js:441:10) 

我发现这个问题是在path中包括node_modules/.bin在本地和ec2机器上工作,因为这些文件只是指向每个相应库中的动作/bin文件夹。 如果这些文件中的调用使用相对path,则中断。 问题:

 [ec2-user@ip-172-31-32-87 .bin]$ ls -lrt total 0 lrwxrwxrwx 1 ec2-user ec2-user 35 Aug 7 00:52 phantomjs -> ../phantomjs-prebuilt/bin/phantomjs lrwxrwxrwx 1 ec2-user ec2-user 24 Aug 7 00:52 casperjs -> ../casperjs/bin/casperjs 

我通过添加每个库各自的bin到Lambda处理函数中的lambdapath来解决这个问题:

 process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'] + ':' + process.env['LAMBDA_TASK_ROOT'] + '/node_modules/phantomjs-prebuilt/bin' + ':' + process.env['LAMBDA_TASK_ROOT'] + '/node_modules/casperjs/bin'; 

这将在Lambda中正确运行幽灵,casper和幽灵。