Reputation: 21
I'm successfully grabbing screenshots from multiple websites using phantomjs via casperjs. I'm having real problems though getting one site, http://fiver.com , to render out the background banner in this element:
<div class="hero-slide sel" style="background-image: url('//cdnil21.fiverrcdn.com/assets/v2_photos/sellerpage-coverphoto-779e2108b002090406e707086772ad9b.jpg');">
<img alt="Sellerpage coverphoto" src="//cdnil21.fiverrcdn.com/assets/v2_photos/sellerpage-coverphoto-779e2108b002090406e707086772ad9b.jpg">
</div>
And then the first three images in <div class="packages-list cf">
don't render either. The images following those render out to png just fine.
Versions being used:
I'm using the following page settings for casperjs:
pageSettings: {
javascriptEnabled: true,
loadImages: true,
loadPlugins: true,
localToRemoteUrlAccessEnabled: true,
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11"
} });
I'm loading the page, which is successfully redirecting to the https url. I'm running with this config file:
{"sslProtocol": "any",
"ignoreSslErrors": true,
"ssl-certificates-path": "ssl",
"web-security": false,
"cookiesFile": "biscuit",
"maxDiskCacheSize": 1000, "diskCache": true }
The code that executes and waits for everything to load is:
this.thenOpen(screenshotUrl, function() {
this.wait(25000);
// Fix transparent background rendering bug
// Courtesy of: http://uggedal.com/journal/phantomjs-default-background-color/
this.evaluate(function() {
// css injection to force backgrounds to print
var style = document.createElement('style'),
text = document.createTextNode('body { background: #fff; -webkit-print-color-adjust: exact; }');
style.setAttribute('type', 'text/css');
style.appendChild(text);
document.head.insertBefore(style, document.head.firstChild);
var images = document.getElementsByTagName('img');
images = Array.prototype.filter.call(images, function(i) { return !i.complete; });
window.imagesNotLoaded = images.length;
Array.prototype.forEach.call(images, function(i) {
i.onload = function() { window.imagesNotLoaded--; };
});
});
});
casper.waitFor(function() {
return this.evaluate(function() {
return window.imagesNotLoaded == 0;
});
});
this.then(function(){
this.echo('Screenshot for ' + viewport.name + ' (' + viewport.viewport.width + 'x' + viewport.viewport.height + ')', 'info');
this.capture('screenshots/' + screenshotDateTime + '/' + viewport.name + '-' + viewport.viewport.width + 'x' + viewport.viewport.height + '.png', {
top: 0,
left: 0,
width: viewport.viewport.width,
height: viewport.viewport.height
});
});
I have tried setting the wait as high as 100000, but it still didn't work.In the evaluate I'm injecting some css and running a function that is trying to wait for all the images to load. Thn I go into my this.then function to render the image to disk.
I'm pulling my hair out with this one.
Here's the screenshot: http://postimg.org/image/flvpvhy6v/
Any ideas?
Upvotes: 1
Views: 1412
Reputation: 61892
JavaScript has no blocking wait or sleep functionality. So when you wait
, you schedule an asynchronous step. Your code contains an evaluate
call after the wait
call. The evaluate
call is synchronous/blocking, but wait
isn't, so the wait
will be executed after the evaluate
. You have to put synchronous code in a callback of a step function like wait*
or then*
.
this.wait(25000, function(){
this.evaluate(function() {
// some code
});
});
Upvotes: 2