phantomjs 不等待“完整”页面加载

2022-08-30 04:04:36

我正在使用PhantomJS v1.4.1来加载一些网页。我无法访问他们的服务器端,我只是获得指向他们的链接。我正在使用过时版本的Phantom,因为我需要在该网页上支持Adobe Flash。

问题是许多网站正在加载他们的次要内容异步,这就是为什么Phantom的onLoadFinished回调(HTML中onLoad的模拟)在不是所有东西都加载时过早地触发。任何人都可以建议我如何等待网页的完全加载来制作,例如,包含广告等所有动态内容的屏幕截图?


答案 1

另一种方法是,按照常规的栅格化示例,在页面加载后,让 PhantomJS 等待一段时间.js,但要有更长的超时时间,以允许 JavaScript 完成加载其他资源:

page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
        window.setTimeout(function () {
            page.render(output);
            phantom.exit();
        }, 1000); // Change timeout as required to allow sufficient time 
    }
});

答案 2

我宁愿定期检查状态(https://developer.mozilla.org/en-US/docs/Web/API/document.readyState)。尽管这种方法有点笨拙,但您可以确定在函数内部使用完全加载的文档。document.readyStateonPageReady

var page = require("webpage").create(),
    url = "http://example.com/index.html";

function onPageReady() {
    var htmlContent = page.evaluate(function () {
        return document.documentElement.outerHTML;
    });

    console.log(htmlContent);

    phantom.exit();
}

page.open(url, function (status) {
    function checkReadyState() {
        setTimeout(function () {
            var readyState = page.evaluate(function () {
                return document.readyState;
            });

            if ("complete" === readyState) {
                onPageReady();
            } else {
                checkReadyState();
            }
        });
    }

    checkReadyState();
});

附加说明:

使用嵌套而不是防止在由于某些随机原因而延长其执行时出现“重叠”和争用条件。 默认延迟为 4ms (https://stackoverflow.com/a/3580085/1011156),因此主动轮询不会对程序性能产生严重影响。setTimeoutsetIntervalcheckReadyStatesetTimeout

document.readyState === "complete"表示文档完全加载了所有资源(https://html.spec.whatwg.org/multipage/dom.html#current-document-readiness)。

编辑2022:我在8年前创建了这个响应,从那时起我就没有使用PhantomJS。在某些情况下,它现在很可能不起作用。此外,现在我认为不可能创建一个一刀切的解决方案来绝对确保页面已加载。这是因为某些页面可能会在文档准备就绪后加载其他资源。例如,网站上可能有一些JS代码等待文档准备就绪,然后加载一些其他资产(在文档状态更改为之后) - 在这种情况下,将触发,之后页面将再次开始加载更多资源。readyonPageReady

我仍然认为上面的截图是一个很好的起点,在大多数情况下可能有效,但也可能是创建特定解决方案来处理特定网站的必要条件。