Selenium PhantomJS 等待图像可用

Selenium PhantomJS wait for image to be available

我正在编写一个通用的基于 selenium phantomjs 的蜘蛛来访问和抓取网页。 程序的输入包括需要抓取的模板(css选择器),输出应该根据模板产生数据。 如果我们尝试从网站抓取图片,有时我们可能会得到空图片(如果执行时的页面源不包含图片,就会出现这种情况),这可以通过 wait 解决 然而,当网页为图像提供占位符时,会出现更具挑战性的问题,这些占位符稍后会通过 ajax 请求被真实图像 URL 替换。

问题是,如何确保 selenium 只在页面中包含真正的 URL 图像后才抓取图像。我正在考虑检查图像的 src 属性是否有更改,只有在一次更改后我才应该开始解析页面源代码。但是,不确定如何实施?或者这是一个好主意吗?


编辑

<html>

<head>
    <style>
    img {
        width: 100%;
        height: auto;
    }
    </style>
</head>

<body>
    <div id='wrapper'>
        <div class='wrapper-child'>
            <img data-backup='./1clr.jpg' src='./1bw.jpg'>
        </div>
        <div class='wrapper-child'>
            <img data-backup='./2clr.jpg' src='./2bw.jpg'>
        </div>
        <div class='wrapper-child'>
            <img data-backup='./3clr.jpg' src='./3bw.jpg'>
        </div>
    </div>
    <script src='./jquery.js'></script>
    <script type='text/javascript'>
    $(document).ready(function() {
        // setTimeout(function() {
            //replace image placeholders
            $.get("ajax/test.html", function(data) {

            }).always(function() {
                $('img').each(function() {
                    $(this).attr('src', $(this).attr('data-backup'));
                });
            });
        // }, 1000);
    });
    </script>
</body>

</html>

假设我有这个页面,在 jquery 更新后如何使用 selenium 抓取图像?

如果该站点正在使用 jQuery,您可以检查以下内容以确保所有 ajax 交互都已完成。

jQuery.active == 0

检查此线程是否有相关问题:wait for an ajax call to complete with Selenium 2 web driver

编辑

此代码适用于我们:

public static int TIME_OUT_SECONDS = 10;
public static int POLLING_MILLISECONDS = 100;

public static final String JS_JQUERY_DEFINED = "return typeof jQuery != 'undefined';";
public static final String JS_JQUERY_ACTIVE = "return jQuery.active != 0;";
public static final String JS_DOC_READY = "return document.readyState != 'complete';";
public static final String JS_BLOCK = "return typeof $ != 'undefined' &&  typeof $.blockSelenium != 'undefined' && $.blockSelenium==true;";


public static void waitForJQuery(final WebDriver driver) {
    new FluentWait<WebDriver>(driver).withTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS).pollingEvery(POLLING_MILLISECONDS, TimeUnit.MILLISECONDS).until(new Function<WebDriver, Boolean>() {

        @Override
        public Boolean apply(final WebDriver input) {
            boolean ajax = false;
            boolean jQueryDefined = executeBooleanJavascript(input, JS_JQUERY_DEFINED);


            if (jQueryDefined) {
                ajax |= executeBooleanJavascript(input, JS_JQUERY_ACTIVE);
            }

            boolean ready = executeBooleanJavascript(input, JS_DOC_READY);
            boolean block = executeBooleanJavascript(input, JS_BLOCK);

            ajax |= ready;
            ajax |= block;

            // continue if all ajax request are processed
            return !ajax;
        }
    });

}


private static boolean executeBooleanJavascript(final WebDriver input, final String javascript) {
    return (Boolean) ((JavascriptExecutor) input).executeScript(javascript);
}