【问题标题】:PhantomJS failing to load Google MapsPhantomJS 无法加载谷歌地图
【发布时间】:2015-04-14 20:44:50
【问题描述】:

我的最终目标是打开一个嵌入了 javascript 的本地 html 文件,创建一个带有多边形的地图,并使用 PhantomJS 对其进行截图。为此,我编写了一个简单的 JS 文件:

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();
}); 

这会返回错误:

ReferenceError: Can't find variable: google

我已经在本地 html 文件和使用谷歌地图的其他网站上尝试过这个,但我一直收到同样的错误。我已经成功地在没有谷歌地图的情况下截取了其他网站的截图。在互联网上搜索似乎没有人遇到过这样的问题,并且已经成功地用谷歌地图截取了页面......所以我想知道可能出了什么问题。

另一个注意事项:我将 PhantomJS 作为 gem 安装在我的 rails 项目中,并使用这个 gem 通过 rails 控制台运行 javascript 文件。我已经使用 PhantomJS (v 2.0.0) 的标准安装进行了尝试,但仍然无法正常工作。

【问题讨论】:

  • 尝试使用--ignore-ssl-errors=true 命令行选项运行。
  • 我可以使用phantomjs script.js 很好地运行您的示例代码。但需要考虑的一点是:Google 地图图块(或这些天的矢量数据)是自行异步加载的,您可能必须在内部 page.open 块周围添加一个等待时间为几秒钟的 window.setTimeout,因此页面是完全加载后呈现为 ​​PDF。否则您的 PDF 将为空白/灰色。
  • @ArtjomB 解决方案对我不起作用:(
  • 上面的 sn-p 对我来说很好用!我正在运行 phantomJS 的 2.1.1 版。

标签: google-maps phantomjs


【解决方案1】:

您必须在 DOM 中等待一个元素。 例如在 maps.google.com 上,您可以等待加载所有图块后加载的水印。

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);
}

如果您想在您开发的页面上截取屏幕截图,请使用与上述相同的逻辑,但您自己在 google maps idle 事件上附加一个元素。

google.maps.event.addListenerOnce(map, 'idle', function () {
    var loadedElem = document.createElement('div');
    loadedElem.setAttribute("id", "idLoadedElem");
    document.body.appendChild(loadedElem);
});

【讨论】:

    【解决方案2】:

    你应该试试puppeter,这很容易:

    const puppeteer = require('puppeteer');
    (async () => {
      const browser = await puppeteer.launch();
      const page = await browser.newPage();
      await page.goto('https://example.com');
      await page.screenshot({path: 'example.pdf'});
    
      await browser.close();
    })();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 2015-08-04
      • 2020-10-12
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      相关资源
      最近更新 更多