我正在使用PhantomJS page.evaluate()进行一些抓取。我的问题是我传递给webkit页面的代码是沙箱,因此无法访问我的主幻像脚本的变量。这使得抓取代码难以通用。
page.open(url, function() {
var foo = 42;
page.evaluate(function() {
// this code has no access to foo
console.log(foo);
});
}
我如何将参数推入页面?
答案 0 :(得分:70)
我遇到了那个确切的问题。它可以通过一些小技巧来完成,因为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);
}
答案 1 :(得分:66)
此更改已被推送,现在您可以将其用作
page.open(url, function() {
var foo = 42;
page.evaluate( function(foo) {
// this code has now has access to foo
console.log(foo);
}, foo);
}
答案 2 :(得分: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
答案 3 :(得分: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 + ')');
)}
});
答案 4 :(得分:2)
您可以将参数作为参数传递给page.evaluate。
示例:
page.evaluate(function(arg1, arg2){
console.log(arg1); //Will print "hi"
console.log(arg2); //Will print "there"
}, "hi", "there");
答案 5 :(得分:0)
这对我有用:
page.evaluate("function() {document.body.innerHTML = '" + size + uid + "'}");
意味着将所有内容都放在一个字符串中。无论如何它后来变成了一个字符串。检查库源。
答案 6 :(得分:0)
你不能将args绑定到函数??
page.evaluate.bind(args)(callbackFn)
答案 7 :(得分:0)
虽然您可以将参数传递给evaluate(function, arg1, arg2, ...),但这通常有点麻烦。特别是在传递几个变量或更糟糕的函数的情况下。
要解决这个障碍,可以使用injectJs(filename)代替。
page.open(url, function() {
if ( webpage.injectJs('my_extra_functionality.js') ) {
page.evaluate( function() {
// this code has access to foo and also myFunction();
console.log(foo);
console.log(myFunction());
});
}
else {
console.log("Failed to inject JS");
}
}
my_extra_functionality.js
是同一目录中的本地文件:
var foo = 42;
var myFunction = function(){
return "Hello world!";
}