Javascript 如何使用casperjs单击一个随机链接并导航到另一个页面?
我正在尝试编写一个脚本,该脚本将执行以下操作:Javascript 如何使用casperjs单击一个随机链接并导航到另一个页面?,javascript,jquery,casperjs,Javascript,Jquery,Casperjs,我正在尝试编写一个脚本,该脚本将执行以下操作: 加载网站并截图 从所有具有相同类名的标记中随机选择一个标记 点击链接 等待新页面加载 捕获第二个屏幕截图 我一直在选择一个随机的元素并单击它。有人能帮我吗?这是我和casperjs在一起的第一天。以下是我目前掌握的情况: var casper = require('casper').create({ verbose: true, logLevel: 'debug', userAgent: 'Mozilla/5.0 (M
标记中随机选择一个
标记
元素并单击它。有人能帮我吗?这是我和casperjs在一起的第一天。以下是我目前掌握的情况:
var casper = require('casper').create({
verbose: true,
logLevel: 'debug',
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22',
pageSettings: {}
});
casper.options.viewportSize = {width: 1600, height: 950};
casper.start('http://www.myurl.com/', function() {
this.echo(this.getTitle());
this.capture('home.png');
});
casper.then(function() {
this.echo("Second test");
var random = Math.floor(Math.random() * document.querySelector(".showall").length);
var clicker = document.querySelector('.showall').eq(random);
this.mouseEvent('click', clicker);
this.wait(5000, function() {
this.capture('second.png');
});
});
casper.run();
不能在页面上下文之外使用DOM函数。你必须用它。请记住,
evaluate
是沙盒,您只能在页面上下文之间传递基本体对象。DOM元素不是基本对象,因此不能将它们从外部传递到casper上下文中<代码>文档表示除评估
之外的任何内容
从:
注意:参数和evaluate函数的返回值必须是一个简单的基元对象。经验法则:如果可以通过JSON对其进行序列化,那么就可以了
您必须在页面上下文中单击带有DOM方法的链接。如果简单的clicker.click()
不起作用,则必须在页面上下文中使用类似的内容
如果该链接实际上是一个可立即导航到该页面的链接,则可以删除this.wait
。CasperJS可以自己感知页面是否被导航到,所以您可以使用另一个casper
顺便说一下,eq
是jQuery语法,但是querySelector
的结果不是jQuery对象,而是DOM元素。如果要选择随机元素,则必须使用querySelectorAll
,然后选择其中一个:
var clicker = document.querySelectorAll('.showall')[random];
相反
完整解决方案:
casper.then(function() {
this.echo("Second test");
this.evaluate(function() {
var elements = document.querySelectorAll(".showall");
var random = Math.floor(Math.random() * elements.length);
var clicker = elements[random];
// either this type of click
clicker.click();
// or the following
var ev = document.createEvent("MouseEvent");
ev.initMouseEvent(
"click", true, true, window, null, 0, 0, 0, 0,
false, false, false, false, 0, null
);
clicker.dispatchEvent(ev);
});
});
casper.then(function() {
this.capture('second.png');
});
我没能让Artjom的解决方案起作用。我想我使用querySelectorAll
的方式不对(不知道为什么)。我找到了一个解决办法
function getElem() {
var arr = document.querySelectorAll('a.showall');
return Array.prototype.map.call(arr, function(elem) {
return elem.getAttribute('href');
});
}
casper.then(function() {
var elem_arr = this.evaluate(getElem);
//this.echo(elem_arr);
this.echo(elem_arr.length);
for (var index = 0; index < elem_arr.length; index++) {
this.echo(elem_arr[index]);
}
var random = Math.floor(Math.random() * elem_arr.length);
this.echo(random);
var clicker = elem_arr[random];
this.echo("Random link: " + clicker);
casper.open(clicker).then(function() {
this.echo('Got it! You navigated to a random link subpage.');
});
});
函数getElem(){
var arr=document.querySelectorAll('a.showall');
返回Array.prototype.map.call(arr,function(elem){
返回elem.getAttribute('href');
});
}
casper.then(函数(){
var elem_arr=这个。评估(getElem);
//这个.echo(elem_arr);
该回波(元素到达长度);
对于(var index=0;index
诀窍是从所有
a.showall
元素创建一个链接数组,然后选择一个随机链接并打开它。如果将random
索引替换为硬编码索引会怎么样?您的脚本是否按预期运行?并非如此。我只需要点击一个特定的元素:casper.then(function(){this.echo(“Second test”);this.mouseEvent('click','.showall');this.wait(5000,function(){this.capture('Second.png');})
通过读取capser的mouseEvent
函数,它似乎期望的是一个选择器查询(即.showall
),而不是.eq()
返回的jQuery对象。如果mouseEvent
的查询选择器使用的是第n个子项
伪选择器,代码是否按预期工作?(即,.showall:nth child(此处插入编号)
)它仅适用于第n个child(1),尽管我100%确定页面上大约有20个
标记。如果第n个子项大于1,我得到CasperError:无法在不存在的选择器上调度click事件:.showall:n个子项(2)
非常感谢您的帮助,Artjom。但是,我注意到,this.evaluate(function()中的所有代码
完全被执行。这是什么原因造成的?我以前在尝试使用评估
时遇到过这个问题。这是一个配置问题吗?似乎不是,但我不完全确定。它被执行了,但您不一定看到结果。您应该注册到和事件。实际上,注册page.error-helped并显示以下错误:error:TypeError:“未定义”不是对象(评估“clicker.click”)
。我完全错过了querySelector
应该是querySelectorAll
。我添加了一个原因。如果答案对您有帮助,请接受。它仍然不起作用,但我会自己找到解决方案。谢谢您的帮助。