2016-08-07 4 views
4

Ich warf eine kleine Lambda-Funktion zusammen, um eine Website mit der SpookyJS-, CasperJS- und PhantomJS-Toolchain zum Headless-Browsing zu crawlen. Die Aufgabe ist ziemlich einfach und irgendwann vor ein paar Monaten funktionierte es in Lambda. Ich musste kürzlich ein paar Dinge ändern und wollte wieder an dem Projekt arbeiten, aber ich begann frisch und hatte Probleme, Lambda zum laufen zu bringen, ohne in irgendeiner Eigenschaft zu irritieren. Meine Frage ist Wie kann ich phantomjs in Lambda laufen lassen?Wie stellt man eine Phantomjs-Knoten-App auf AWS Lambda bereit?

Der Beispielcode Ich betreibe ist:

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(); 

Der Fehler, den ich in Lambda bin immer ist:

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

Ich habe eine Vielzahl von Verfahren, gefolgt alles, um sicherzustellen, ist in der Lage auf denen sie laufen Lambda. Im Folgenden finden Sie eine lange Liste von Dingen, die ich versucht habe zu diagnostizieren:

lokal
  1. Run node index.js und bestätigen Sie mit
  2. Hochladen package.json und die js-Datei in eine Amazon Linux EC2-Instanz für die Kompilierung wie empfohlen arbeitet für npm Installation Anrufe und beschrieben here
  3. Run npm install auf der EC2-Instanz, und wieder node index.js läuft die korrekte Ausgabe
  4. zip alles auf, und bereitstellen, um AWS mit dem cli
, um sicherzustellen,

Mein package.json ist:

{ 
    "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" 
    } 
} 

ich auch die folgenden versucht haben (die meisten auch vor Ort arbeiten und auf der AWS EC2-Instanz, aber mit dem gleichen Fehler auf Lambda:

  1. Der Versuch, die nicht -prebuilt Version von Phantom sind
  2. casperjs und PhantomJS Gewährleistung zugänglich aus dem Weg mit 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. inspizieren Laich ruft b y Wickel child_process der .spawn() Anruf, und bekam die folgenden:

    { '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. Aufruf .exec('casperjs') und .exec('phantomjs --version') direkt, es funktioniert lokal und auf EC2 bestätigt, sondern erhält den folgenden Fehler in Lambda. Der Befehl:

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

beide mit folgendem Ergebnis:

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) 

Antwort

3

fand ich das Problem zu sein, dass die node_modules/.bin im Pfad einschließlich arbeitet auf lokale und EC2 Maschinen, weil diejenigen, Dateien zeigen einfach auf die Aktion /bin Ordner in der jeweiligen Bibliothek. Dies bricht ab, wenn Aufrufe innerhalb dieser Dateien relative Pfade verwenden.Das Problem:

[[email protected] .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 

arbeitete ich um diesen von jeder Bibliothek der jeweiligen Behälter zu dem Lambda-Pfad in der Lambda-Handler-Funktion hinzugefügt:

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'; 

Und das wird jetzt laufen Phantom, casper, und gespenstische richtig in Lambda.

+0

Falls jemand anderes dies findet und ein ähnliches Problem hat. Selbst nach dem oben Gesagten, litt ich immer noch unter "Kind beendet mit Nicht-Null-Exit-Code 1". Es stellte sich heraus, dass ich in das Casperjs-Verzeichnis unter node_modules gehen und npm_update ausführen musste, da Abhängigkeiten fehlten, von denen nicht richtig bezogen wurde das Elternteil – Nick

Verwandte Themen