2

私は、コード化がかなり悪く、恐ろしく遅い Web サイトと対話しようとしています。私が抱えている問題を例で説明します。

この Web ページには 2 つの選択ボックスがあり、最初の 1 つは国を選択するために使用され、変更時に Web サーバーに対して AJAX 要求が行われ、都市のリストが返されます。このリストは、2 番目の選択ボックスに入力するために使用されます。問題は、phanomtjs の page オブジェクトで evaluate 関数を使用して、最初の選択ボックスを反復処理し、正しいオプションを選択できることです。しかしその後、2 番目のボックスに値が入力されるまで n 秒待たなければなりません。現在、2 番目のボックスから都市を選択する前にタイマーを 25 秒間待機するように設定することで、これを「解決」しました。ただし、これは非常に悪い解決策です。まず、25 秒ではすべての状況で十分な長さではないため、タイムアウトして失敗することがあります。2 番目の問題は、ほとんどの場合、25 秒では長すぎることです。

そのため、2 番目のボックスが読み込まれるまで待機する方法を見つける必要があります。最初は、評価関数内で setInterval を使用して、選択ボックスに値が入力されているかどうかをテストできました。これは機能しますが、問題があります。setInterval は非同期であるため、このメソッドを使用すると、正しい選択が行われたかどうかを確認できなくなります。私が何を意味するかを説明するために、以下のコードは、待機する必要がないときにどのように機能するかを示しています。

var retval = page.evaluate(function () {
    return selectOption('select_id',
                        info['country']);
});

その selectOption は、適切なオプション要素が見つかるまで select 要素を反復する関数です。失敗した場合は false を返します。この戻り値は評価された関数によって返されるため、機能したかどうかを確認できます。

もう 1 つのオプションは、Web ページのコンテキスト内で setInterval を使用して待機し、失敗した場合に例外を発生させることです。これをやってみましたが、Web サイトの範囲外で例外をキャッチできないようです。PhantomJS はターミナルに例外をダンプしますが、インターセプトできません。

これを回避する方法はありますか?それとも、固定待ち時間オプションを使用する必要がありますか?

編集:page.onErrorを使用しようとしましたが、慣れていないようです。

4

1 に答える 1

0

また、評価された関数で例外がスローされたかどうかを確認する必要もありました。関数を try-catch でラップした別のレイヤーを追加することで、これを行うことができました。

// Wrap a function (func) inside a try-catch block and return
// the exception if any. Otherwise return null. The ctx is a
// a bucket for all the variables to be passed to func.
var tryCatchWrapper = function(func, ctx) {        
    try {
        funct(ctx);
    }
    catch(e) {
        return e;
    }

    return null;
}

次に、評価somefunctionするために、次のように使用します。

var error = page.evaluate(tryCatchWrapper, somefunction);
if (error) {
    handle error...
}

func に引数を渡したい場合は、コンテキスト オブジェクトを使用します。関数に可変引数を渡す方法に関する別のアプローチについては、質問「JavaScript variable number of arguments to function」を参照してください。

于 2014-02-06T08:25:09.910 に答える