javascript - 在一个脚本中使用多个 page.open

标签 javascript phantomjs

我的目标是打开很多页面(延迟很短)并将我的数据保存到一个文件中。

但是我的代码不起作用。

var gamesList = [url1,url2,url3];
//gamesList is getting from a file

var urls = [];
var useragent = [];
useragent.push('Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14');
useragent.push('Opera/9.80 (X11; Linux x86_64; U; fr) Presto/2.9.168 Version/11.50');

var page = require('webpage').create();
page.settings.userAgent = useragent[Math.floor(Math.random() * useragent.length)];
console.log('Loading a web page');


function handle_page(url){
    page.open(url,function(){
        //...
        var html= page.evaluate(function(){
            // ...do stuff...
            page.injectJs('jquery.min.js');
            return $('body').html();
        });
        //save to file
        var file = fs.open('new_test.txt', "w");
        file.write(html + '\n');
        file.close();    

        console.log(html);

        setTimeout(next_page,1000);
    });
}

function next_page(urls){
    var url=urls.shift();
    if(!urls){
        phantom.exit(0);
    }
    handle_page(url);
}

next_page(urls);
phantom.exit();

我在哪里写 phantom.exit(); 重要吗?如果我最后在 page.open() 回调中编写它,那么第一个页面打开得很好。

最佳答案

你用递归打开多个页面的想法是正确的,但是你有一些问题。

退出

正如您正确指出的那样,phantom.exit() 有问题。由于 page.open()setTimeout() 是异步的,你只需要在完成后退出。当您在脚本末尾调用 phantom.exit() 时,您甚至在第一页加载之前就退出了。

只需删除最后一个 phantom.exit(),因为您已经在正确的位置有另一个导出。

页面上下文

page.evaluate() 提供对 DOM 上下文(页面上下文)的访问。问题是它是沙盒的。在该回调内部,您无权访问外部定义的变量。您可以显式传递变量,但它们必须是 page 不是的原始对象。您只需访问 page.evaluate() 中的 page。您需要在调用 page.evaluate() 之前注入(inject) jQuery。

文件

您通过不更改文件名来在每次迭代中覆盖文件。您需要更改文件名或使用附加模式 'a' 而不是 'w'

那么当你只想写一次时就不需要打开一个流。变化:

var file = fs.open('new_test.txt', "w");
file.write(html + '\n');
file.close();

fs.write('new_test.txt', html + '\n', 'a');

递归步骤

调用 next_page() 函数的递归步骤要求您传入 url。由于 urls 已经是一个全局变量并且您在每次迭代中更改它,因此您不需要传入 urls

您也不需要添加 setTimeout(),因为 page.open() 回调之前的所有内容都是同步的。

固定脚本

//...
var urls = [/*....*/];

function handle_page(url){
    page.open(url, function(){
        //...
        page.injectJs('jquery.min.js');
        var html = page.evaluate(function(){
            // ...do stuff...
            return $('body').html();
        });
        //save to file
        fs.write('new_test.txt', html + '\n', 'a');

        console.log(html);

        next_page();
    });
}

function next_page(){
    var url = urls.shift();
    if(!url){
        phantom.exit(0);
    }
    handle_page(url);
}

next_page();

关于javascript - 在一个脚本中使用多个 page.open,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31188021/

相关文章:

javascript - visual studio typescript 与angular 2冲突

javascript - 在 ios 上运行后台任务 - react native 0.60

javascript - Karma 无法在 Visual Studio Online 上运行 'PhantomJS have not captured in 60000 ms, killing.'

node.js - 无法在 Node js 上使用 mocha 运行 PhantomJS

javascript - 从 CLI 或 Web 调用时 PhantomJS 挂起

javascript - 解释 Javascript 文件 Laravel 中的变量

javascript - 如何使用 Javascript 而不是 jQuery 来实现scrollTop 和toggleClass?

javascript - ng-class 在一个 ng-class 指令中具有条件和函数

javascript - 使用 headless 浏览器 Phantomjs 打开 PDF

javascript - 在PhantomJS中使用页面标题作为截图文件名