如何使用PhantomJS导航分页网站?

时间:2015-02-17 10:58:26

标签: javascript phantomjs

我需要导航一个分页的网站,分页会激活一个Ajax请求,该请求会为页面带来新数据。

现在我有一个工作示例代码,等待20秒,然后点击链接(" ul.pageNavi li.next")。

url = 'https://www.somewebsite.com';

// open the url
var page = require('webpage').create();
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 5.2; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0';
page.open(url, function (status) {


    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
        window.setTimeout(function () { // Wait 20 seconds so the page loads

            page.render('1.png');

            // Begin - click on the pagination 
            page.evaluate( function() {
                // find element to send click to
                var element = document.querySelector( 'ul.pageNavi li.next' );

                // create a mouse click event
                var event = document.createEvent( 'MouseEvents' );
                event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );

                // send click to element
                element.dispatchEvent( event );                     
            });         
            // End - click on the pagination        

            page.render('2.png');

            phantom.exit();
        }, 20000); // Change timeout as required to allow sufficient time 
    }

});

上面的代码正常运行,我成功进入了第2页。现在我陷入了实现循环的困境,所以我可以导航到以下页面。

我需要在每次点击之间等待几秒钟,我已实施此代码,但这不起作用。

url = 'https://www.somewebsite.com';

// open the url
var page = require('webpage').create();
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 5.2; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0';
page.open(url, function (status) {


    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
        window.setTimeout(function () { // Wait 20 seconds so the page loads

            var morelinks = moreLinks();
            var i = 0;

            page.render(i + '.png');
            console.log('1: ' + morelinks); 

            while (morelinks != 0) {
                window.setTimeout(function () { // Wait 20 seconds so the page loads

                    i++;

                    // Begin
                    page.evaluate( function() {
                        // find element to send click to
                        var element = document.querySelector( 'ul.pageNavi li.next' );

                        // create a mouse click event
                        var event = document.createEvent( 'MouseEvents' );
                        event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );

                        // send click to element
                        element.dispatchEvent( event );                     
                    });         
                    // End

                    page.render(i + '.png');

                    morelinks = moreLinks();
                    console.log('2: ' + morelinks);

                }, 20000); // Change timeout as required to allow sufficient time  
            }           

            phantom.exit();
        }, 20000); // Change timeout as required to allow sufficient time 
    }

});

function moreLinks() {
    var morelinks = page.evaluate(function() {
        return $('ul.pageNavi li.next').length;
    });

    return morelinks;
}

function getHref() {
    var links = page.evaluate(function() {
        return $('#ulSearchResults li a');
    }); 

    return links;
}

有人可以告诉我如何实现导航到以下页面吗?

1 个答案:

答案 0 :(得分:1)

你有两个问题。

提前退出

您正在处理异步函数(在循环中)。循环结束后,立即退出(phantom.exit())。此时,所有异步函数都没有开始执行。

异步函数循环

如果从循环调用它们,您应该问自己如何评估异步函数。循环结束后,尚未执行任何功能。在第一次超时触发后,所有其他超时也会触发,因为setTimeout基本上同时被调用。

有很多方法可以解决这个问题。这是两个:

1。静态超时延迟

按照从前一个函数延迟调用它们的方式安排超时。

while (morelinks != 0) {
    // IIFE to keep a proper reference to `i`
    (function(i){
        setTimeout(function () {
            // do your stuff
        }, 20000 * i);
    })(i);
    i++;
}

2。递归(推荐

在伪代码和真实代码之间混合。

function scrapePage(){
    page.render(i + '.png');
    if (exists(".next")) {
        click(".next");
        setTimeout(function (){
            scrapePage();
        }, 5000);
    } else {
        phantom.exit();
    }
}

page.open(url, function(){
    scrapePage();
});

关键是检查下一个按钮是否存在(或者是可见还是已启用),然后单击它。如果不是,那么您知道您已经在最后一页上,并且可以安全退出。

我们确定您可以自己实施exists()click()功能。

使用waitFor

不要在第二个建议中等待静态时间,而是使用示例中的waitFor函数等待页面完全加载,方法是查找适合的选择器装了最后一个。