60

PhantomJS page.evaluate() を使用してスクレイピングを行っています。私の問題は、Webkit ページに渡すコードがサンドボックス化されているため、メインのファントム スクリプトの変数にアクセスできないことです。これにより、スクレイピング コードを一般化することが難しくなります。

page.open(url, function() {
  var foo = 42;

  page.evaluate(function() {
    // this code has no access to foo
    console.log(foo);
  });
}

ページに引数をプッシュするにはどうすればよいですか?

4

8 に答える 8

81

私はその正確な問題を抱えていました。page.evaluate文字列も受け入れることができるので、ちょっとしたトリックで実行できます。

いくつかの方法がありますが、私は というラッパーを使用します。このラッパーevaluateは、Webkit 側で評価する必要がある関数に渡す追加パラメーターを受け入れます。次のように使用します。

page.open(url, function() {
  var foo = 42;

  evaluate(page, function(foo) {
    // this code has now has access to foo
    console.log(foo);
  }, foo);
});

そして、ここにevaluate()関数があります:

/*
 * This function wraps WebPage.evaluate, and offers the possibility to pass
 * parameters into the webpage function. The PhantomJS issue is here:
 * 
 *   http://code.google.com/p/phantomjs/issues/detail?id=132
 * 
 * This is from comment #43.
 */
function evaluate(page, func) {
    var args = [].slice.call(arguments, 2);
    var fn = "function() { return (" + func.toString() + ").apply(this, " + JSON.stringify(args) + ");}";
    return page.evaluate(fn);
}
于 2012-03-23T11:13:38.433 に答える
73

変更がプッシュされ、次のように使用できるようになりました

page.open(url, function() {
  var foo = 42;

  page.evaluate( function(foo) {
  // this code has now has access to foo
  console.log(foo);
  }, foo);
}

プッシュの詳細はこちら: https://github.com/ariya/phantomjs/commit/81794f9096

于 2012-06-28T01:58:27.083 に答える
12

関数への引数を page.evaluate への引数として渡すことができます。

例:

page.evaluate(function(arg1, arg2){
    console.log(arg1); //Will print "hi"
    console.log(arg2); //Will print "there"
}, "hi", "there");
于 2018-05-17T03:54:42.213 に答える
3

PhantomJS 0.9.2 および 0.2.0 で動作するソリューションがあります。

page.evaluate(
    function (aa, bb) { document.title = aa + "/" + bb;}, //the function
    function (result) {}, // a callback when it's done
    "aaa", //attr 1
    "bbb"); //attr 2
于 2015-02-20T12:47:36.627 に答える
2

別の可能性: url で変数を渡します。たとえば、オブジェクト x を渡すには

// turn your object "x" into a JSON string
var x_json = JSON.stringify(x);

// add to existing url
// you might want to check for existing "?" and add with "&"
url += '?' + encodeURIComponent(x_json);

page.open(url, function(status){
    page.evaluate(function(){
        // retrieve your var from document URL - if added with "&" this needs to change
        var x_json = decodeURIComponent(window.location.search.substring(1));
        // evil or not - eval is handy here
        var x = eval('(' + x_json + ')');       
    )}
});
于 2012-05-22T03:45:52.307 に答える
1

これは私のために働く:

page.evaluate("function() {document.body.innerHTML = '" + size + uid + "'}");

すべてを文字列にすることを意味します。とにかく後で文字列になります。ライブラリのソースを確認してください。

于 2015-02-17T19:39:46.330 に答える