PhantomJSノードモジュール( https://github.com/sgentle/phantomjs-node )を使用してFacebookページをスクレイピングしていますが、ページを評価しようとすると、関数Iが評価されません。それに渡します。スタンドアロンスクリプトで実行し、Nodeインタープリターで実行すると機能します。Express.jsアプリの同じコードは機能しません。
これは私のコードです
facebookScraper.prototype.scrapeFeed = function (url, cb) {
f = ':scrapeFeed:';
var evaluator = function (s) {
var posts = [];
for (var i = 0; i < FEED_ITEMS; i++) {
log.info(__filename+f+' iterating step ' + i);
log.info(__filename+f+util.inspect(document, false, null));
}
return {
news: posts
};
}
phantom.create(function (ph) {
ph.createPage(function (page) {
log.fine(__filename+f+' opening url ' + url);
page.open(url, function (status) {
log.fine(__filename+f+' opened site? ' + status);
setTimeout(function() {
page.evaluate(evaluator, function (result) {
log.info(__filename+f+'Scraped feed: ' + util.inspect(result, false, null));
cb(result, ph);
});
}, 5000);
});
});
});
};
私が得る出力:
{"level":"fine","message":"PATH/fb_regular.js:scrapeFeed: opening url <URL> ","timestamp":"2012-09-23T18:35:10.151Z"}
{"level":"fine","message":"PATH/fb_regular.js:scrapeFeed: opened site? success","timestamp":"2012-09-23T18:35:12.682Z"}
{"level":"info","message":"PATH/fb_regular.js:scrapeFeed: Scraped feed: null","timestamp":"2012-09-23T18:35:12.687Z"}
したがって、ご覧のとおり、null引数を使用してファントムコールバック関数(evaluate関数の2番目のパラメーター)を呼び出しますが、最初のパラメーター(反復ステップXを出力する私の評価関数)は実行しません。
誰もが問題が何であるか知っていますか?
使用しているPhantomJSのバージョンはわかりませんが、バージョン1.6以降のドキュメントについては、評価されたスクリプト内にログを記録すると、含まれているページに結果が記録されます。コンソールにはログインしません。これを取得するには、ログをページonConsoleMessageイベントにバインドする必要があります。
page.onConsoleMessage = function (msg) { console.log(msg); };
結果が利用できない場合:page.evaluate関数は、次のような引数を取ります。最初の関数は実行される関数であり、残りはその関数への入力として渡されます。結果は直接返されます:
var title = page.evaluate(function (s) {
return document.querySelector(s).innerText;
}, 'title');
console.log(title);
evaluate
はサンドボックスモードで実行されます。つまり、cb
や、phantom
オブジェクトやその他の関数など、包含環境で定義された変数は使用できません。定義されています。
evaluate
への追加の引数として、情報をサンドボックスに明示的にトンネリングできます。
page.evaluate(function(cb){...}, cb);
PhantomJSのpage.evaluate()
関数は、DOMコンテキスト(ページコンテキスト)への扉です。この関数を介してのみDOMにアクセスできます。関数はサンドボックス化されているため、関数の外部で定義された変数を使用することはできず、明示的に渡す必要があります。ただし、受け渡しできるものには制限があります( docs ):
注:引数と
evaluate
関数への戻り値は、単純なプリミティブオブジェクトである必要があります。経験則:JSONを介してシリアル化できる場合は、問題ありません。クロージャ、関数、DOMノードなどは機能しません機能しません!
phantomjs-node はPhantomJSとnode.jsの間のブリッジであるため、PhantomJS自体とはわずかに異なるAPIを使用します。 PhantomJSで同期している関数は、phantomjs-nodeでは何も返しませんが、結果が渡されるコールバックを受け取ります。コールバックは外部コンテキストで実行され、サンドボックス化されません。
引数は次のように渡すことができます。
page.evaluate(function(arg1, arg2){
// use arg1 and arg2 in the page
// return `result`
}, function(result){
// use `result` in the node context
}, "some arg1", "another arg");
以下は私がページを評価するのに役立ちました:
page.evaluate(function(s) {
return document.querySelector(s)
}, 'body').then(res => {
console.log(res)
})
Console.log行のみが内部にある評価ブロックがあり、実行されない人がいます。これは必ずしもサンドボックスの問題ではありません。
リンクを参照してください: PhantomJSではjQueryを含めることができず、jQueryがないとフォームデータを投稿できません