我正在尝试分析 PhantomJS 中的 anchor 链接(它们的 text
属性)。
检索发生在这里:
var list = page.evaluate(function() {
return document.getElementsByTagName('a');
});
这将返回一个具有属性 length
的对象,这很好(与我在运行 document.getElementsByTagName('a') 时得到的相同
在控制台中)。但是对象中的绝大多数元素都具有 length
);null
的值,这并不好。我不知道为什么会这样。
我一直在尝试通过 slice
转换为真正的数组,但效果不佳。我试过不同的网站,没有区别。我已转储 .png 文件以验证加载是否正确,网站是否已正确加载。
这显然不是完整的脚本,而是一个在众所周知的公共(public)站点上显示问题的最小脚本;)
如何从加载的页面中检索完整的 anchor 列表?
var page = require('webpage').create();
page.onError = function(msg, trace)
{ //Error handling mantra
var msgStack = ['PAGE ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
});
}
console.error(msgStack.join('\n'));
};
phantom.onError = function(msg, trace)
{ //Error handling mantra
var msgStack = ['PHANTOM ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : ''));
});
}
console.error(msgStack.join('\n'));
phantom.exit(1);
};
function start( url )
{
page.open( url , function (status)
{
console.log( 'Loaded' , url , ': ' , status );
if( status != 'success' )
phantom.exit( 0 );
page.render( 'login.png');
var list = page.evaluate(function() {
return document.getElementsByTagName('a');
});
console.log( 'List length: ' , list.length );
for( var i = 0 ; i < list.length ; i++ )
{
if( !list[i] )
{
console.log( i , typeof list[i] , list[i] === null , list[i] === undefined );
//list[i] === null -> true for the problematic anchors
continue;
}
console.log( i, list[i].innerText , ',' , list[i].text /*, JSON.stringify( list[i] ) */ );
}
//Exit with grace
phantom.exit( 0 );
});
}
start( 'http://data.stackexchange.com/' );
//start( 'http://data.stackexchange.com/account/login?returnurl=/' );
最佳答案
当前版本的 phantomjs 仅允许原始类型( bool 值、字符串、数字、[]
和 {}
)传入和传出页面上下文。所以基本上所有功能都将被剥离,这就是 DOM 元素。 t.niese found the quote来自 docs :
Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.
Closures, functions, DOM nodes, etc. will not work!
您需要在页面上下文中完成一部分工作。如果你想要每个节点的 innerText
属性,那么你需要先将它映射到原始类型:
var list = page.evaluate(function() {
return Array.prototype.map.call(document.getElementsByTagName('a'), function(a){
return a.innerText;
});
});
console.log(list[0]); // innerText
您当然可以同时映射多个属性:
return Array.prototype.map.call(document.getElementsByTagName('a'), function(a){
return { text: a.innerText, href: a.href };
});
关于javascript - 检索到的 anchor 列表已损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24700432/