Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PhantomJS failing to load Google Maps

My end goal is to open a local html file with javascript embedded, creating a map with polygons, and take a screenshot of it using PhantomJS. I have written a simple JS file to do this:

var page = require('webpage').create();
page.open('https://www.google.com/maps', function(status) {
  console.log('State: ' + status);
  if(status === 'success') {
      page.render('example.pdf', {format: 'pdf', quality: '100'});
  }
  phantom.exit();
}); 

This returns the error:

ReferenceError: Can't find variable: google

I've tried this on a local html file and on other websites using google maps and I keep getting the same error. I have been successful in taking a screenshot of other websites without google maps. Searching the internet it doesn't seem like people have had issues like this, and have been successful in taking screenshots of pages with google maps...so I'm wondering what could be wrong.

Another note: I installed PhantomJS as a gem in my rails project and am running the javascript file through the rails console using this gem. I have tried it using the standard installation of PhantomJS (v 2.0.0) and it still didn't work.

like image 657
CCIS_Student Avatar asked Apr 14 '15 20:04

CCIS_Student


1 Answers

You'll have to wait for an element in the DOM. for example on maps.google.com, you can wait for the watermark which is loaded after all tiles are loaded.

var page = require('webpage').create();
page.open('https://www.google.com/maps', function (status) {
    console.log('State: ' + status);
    if (status === 'success') {
        waitFor(function () {
            return page.evaluate(function () {
                var document_contains_watermark =
                    document.body.contains(document.getElementById('watermark'));
                return document_contains_watermark;
            });
        }, function () {
            page.render('maps-google-com.pdf', {format: 'pdf', quality: '100'});
            phantom.exit();
        });
    }
});

function waitFor(testFn, onReady) {
    var loaded = false;
    var interval = setInterval(function () {
        loaded = testFn();
        if (loaded) {
            onReady();
            clearInterval(interval);
        }
    }, 1000);
}

If you want to take a screenshot on a page that you developed, use the same above logic but append by yourself an element on the google maps idle event.

google.maps.event.addListenerOnce(map, 'idle', function () {
    var loadedElem = document.createElement('div');
    loadedElem.setAttribute("id", "idLoadedElem");
    document.body.appendChild(loadedElem);
});
like image 186
Gael Avatar answered Nov 24 '22 18:11

Gael