问题
I'm trying to use CasperJS as a web scraper, and there's a page with buttons that will load data when clicked. So, I'd like to click all of these buttons first and wait before actually making a query to grab all the necessary data.
The problem is that with Casper, casper.thenClick(selector)
clicks the first element. But how do you iterate and click each element based on the selector?
Note that these buttons do not have ids. They all have generic class selectors.
Ex.
<h3>
<span>Text 1</span>
<span>
<button class="load-btn">show</button>
</span>
</h3>
<h3>
<span>Text 2</span>
<span>
<button class="load-btn">show</button>
</span>
</h3>
<h3>
<span>Text 3</span>
<span>
<button class="load-btn">show</button>
</span>
</h3>
And for some reason casper.thenClick("h3:contains('text 1') .load-btn")
doesn't work.
回答1:
I created a new 'click' function, you can click on each element by using for
cycle:
function click(sel){var event=document.createEvent('MouseEvents');event.initMouseEvent('click',1,1,window,1,0,0,0,0,0,0,0,0,0,null);sel.dispatchEvent(event);}
var casper = require('casper').create({
verbose: true,
logLevel: 'debug',
waitTimeout: 5000,
userAgent: 'Mozilla/5.0 (X11; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0',
viewportSize:{width: 1600, height: 900}
});
casper
.on("error", function(msg){ this.echo("error: " + msg, "ERROR") })
.on("page.error", function(msg, trace){ this.echo("Page Error: " + msg, "ERROR") })
.on("remote.message", function(msg){ this.echo("Info: " + msg, "INFO") })
.start("http://domu-test-2/node/12", function(){
this.evaluate(function(click){
var i, x = document.querySelectorAll("button.load-btn");
for(i = 0; i < x.length; i++) {
click(x[i]);
} //'click' for each element
}, click);
})
.run();
With this HTML:
<h3>
<span>Text 1</span>
<span>
<button class="load-btn" onclick='console.log("1")'>show</button>
</span>
</h3>
<h3>
<span>Text 2</span>
<span>
<button class="load-btn" onclick='console.log("2")'>show</button>
</span>
</h3>
<h3>
<span>Text 3</span>
<span>
<button class="load-btn" onclick='console.log("3")'>show</button>
</span>
</h3>
Will print:
Info: 1
Info: 2
Info: 3
In green color.
回答2:
You could try dropping into the DOM using evaluate instead (I assume the page has jquery on it).
casper.thenEvaluate(function() {
$('button.load-btn').click();
});
Remember that you will need to WAIT for something to appear afterwards.
casper.wait(2000, function() {...});
or using one of the waitFor function
来源:https://stackoverflow.com/questions/40913522/casperjs-how-do-you-click-on-all-selected-buttons