3

これは少し難しい質問です。

私はjavascriptに精通していますが、PhantomJSとCasperJSを使用してWebサイトを自動クロールするプロジェクトに参加しています。これらは私にとって全く新しい主題です。

Casperの使用方法とナビゲート方法、ページへのログイン方法などを理解することができましたが、一般的なフローは次のように思われるため、扱いにくいです。

casper.start('http://google.fr/');

casper.then(function() {
    this.echo("I'm in your google.");
});

casper.then(function() {
    this.echo('Now, let me write something');
});

casper.then(function() {
    this.echo('Oh well.');
});

casper.run();

これに関する私の問題は、Webサイトで取得するデータに応じて、Webサイトでさまざまなことを実行したいということです。ナビゲーションのシーケンスを事前にレイアウトすることはできず、変更することもできません。これが理にかなっていることを願っています。

これを解決するために、組み込み関数を使用してJavascriptNavigatorオブジェクトを作成しました。私の一般的な概念は次のとおりです。

navigator.logIn(function() 
{
  navigator.actionA(parameters, function() 
  {
    if (navigator.data.a == navigator.data.b) {
      navigator.actionB();
    } else {
      navigator.actionC();
    }
  });
});

そして、これらの各関数には、casper関数が組み込まれています。

これが私の実際のコードの短縮版であり、物事がファンキーになり始めたところです:

var casper = require('casper').create({
    clientScripts:  [ 'jquery.min.js' ],
    onError: function(self, m) {  
        console.log('FATAL:' + m);
        self.exit();              
    },
});

var navigator = new _Navigator();

function _Navigator() { }

_Navigator.prototype.logIn = function(aCallback)
{
  var self = this;

  casper.start('https://website/login.asp', function() 
  {
    if (1 == 1) {
      this.evaluate(function() {
        $("input[name=blah]").val('blahblah');
      });

      // ... A LOT MORE CODE
      aCallback();
    }
  });  
}

_Navigator.prototype.search = function(aDataSet, aCallback)
{
  var self = this;

  console.log('this works');
  casper.then(function(){
    console.log('this works');
  });

  var firstName = 'foobar';

  casper.then(function(){
    console.log('this works');
    this.evaluate(function()
    {
      console.log('this no longer works!!');
      $('input[id=blah]').val(firstName);
      aCallback();
    });
  });
}

navigator.logIn(function() {
  // LOG IN RUNS, AND CALLS BACK SUCCESSFULLY...
  navigator.search({'dataset'}, function() 
  {
    console.log('This never runs');
  });
});

casper.run();

navigator.login関数で、casper.start();を呼び出していることに気付くでしょう。この場合、評価関数は正常に機能しますが、そのcasper.start()内でコールバック関数を実行します。コールバックでは、次の関数navigator.searchを呼び出します。これは、まだ技術的にcasper.startで実行されていると思いますか?

最初のコールバック関数によって呼び出されたこの新しい関数内でcasper.evaluateを実行しようとすると、casper.evaluateが機能しなくなったことを除いて、すべてが正常に動作しているように見えます。コンソールログなどを出力するのではなく、機能を消費しているようです。

私はこれですべてを試しました。これを正しく行う方法がわかりません。誰かが私が間違っていることについて何か提案がありますか?ありがとう。

4

2 に答える 2

4

これがかなり古いことは知っていますが、ここで起こっていることは、次の 2 つの問題の組み合わせです。

  • casper.evaluate()現在のスタック内のすべてのエラーを食べているようです -コールバックonError内からは実行されません。.evaluate()

  • で使用される関数は標準クロージャーで.evaluateはありません。それらはサンドボックス化されており、明示的な引数として に渡されない限り、スコープ外の変数にはアクセスできませんcasper.evaluate。したがって、呼び出した評価された関数にはスコープがaCallback()なく、関数は (黙って) で失敗します。aCallbackReferenceError

于 2013-09-10T23:04:04.217 に答える
0

casper.evaluate() は、ヘッドレス ブラウザ セッションへのウィンドウです。evaluate に渡された関数で発生することは、ローカル コンソールには表示されません。ただし、評価から返された値をログに記録するか、リスナーを設定してすべての出力を出力することができます。

  casper.on('remote.message', function(message) {
    console.log(message);
  });
于 2014-01-20T05:10:35.027 に答える