问题
I'm trying to write a step that clicks a more button until that button changes to display: none;
.
CLARIFICATION: The page I'm working with is a Google+ business page. There is a more button that loads about 10 reviews at a time until they are all loaded. Once they are, Google sets the button to display: none;
I've played around with a ton of different ways to accomplish it. Right now I'm working with something like:
This one is not working, and I'm sure there is an elegant way to accomplish this.
casper.then(function() {
while (this.visible('.d-s.L5.r0')){
console.log("Click");
this.click('.d-s.L5.r0');
}
});
This new code is working, but I have to set how many times it repeats which is pretty hacky:
casper.repeat(15, function() {
console.log("Click");
this.click('.d-s.L5.r0');
this.wait(400);
});
回答1:
You need proper status handling of the button. By clicking the more button it will be invisible, but another loading span
will be visible until the next items are loaded. Then it is exchanged again. You need to reflect the change in your code.
if (this.visible(moreButton)) { // synchronous
// asynchronous steps...
this.thenClick(moreButton);
this.waitUntilVisible(loadingButton);
this.waitUntilVisible(moreButton);
this.then(function(){
this.capture("business.png"); // overwrite the current screenshot
// recursion here
});
}
Additionally, it is good practice to write the thing recursive, because you don't know the number of steps until you try the steps. So the complete code would be:
var casper = require('casper').create({
waitTimeout: 10000,
viewportSize: {
width: 900,
height: 720
}
});
var moreButton = '[id*="about-page"] span.d-s.L5.r0',
loadingButton = moreButton + ' + span.dP.PA';
function clickMore(max, i){
i = i || 0;
if ((max == null || i < max) && this.visible(moreButton)) { // synchronous
// asynchronous steps...
this.thenClick(moreButton); // sometimes the click is not properly dispatched
this.waitUntilVisible(loadingButton);
this.waitUntilVisible(moreButton, null, function onTimeout(){
// only placeholder so that the script doesn't "die" here if the end is reached
});
this.then(function(){
this.capture("business_"+i+".png");
clickMore.call(this, max, i+1); // recursion
});
}
}
casper.start("https://plus.google.com/101200069268247335090/about?hl=en").then(function(){
clickMore.call(casper);
}).then(function(){
this.capture("business_end.png");
}).run(function(){
this.echo("DONE");
this.exit();
});
You can also call clickMore
with an argument setting the maximum number of clicks like this:
clickMore.call(casper, 10);
A problem remains. The click on the more button is sometimes not dispatched. You should explore other approaches clicking that button.
来源:https://stackoverflow.com/questions/24644557/how-to-click-a-button-until-the-button-isnt-visible