如何停止CasperJS执行并让用户输入一些值然后继续执行?

时间:2014-10-24 20:28:38

标签: javascript automation phantomjs captcha casperjs

我使用 PhantomJS CasperJS 来自动执行某些任务。在其中一项任务中,我需要在实际处理任务之前手动提供验证码字符串。对于这个问题,我能想到的是捕获网页的屏幕截图,然后手动检查捕获的图像并将验证码字符串保存到文本文件中。之后,我可以使用 CasperJS 中的文件系统模块来读取该值并继续执行该过程。我想知道做这种任务的最佳方法是什么。

1 个答案:

答案 0 :(得分:12)

由于CasperJS与PhantomJS相比具有结构化的方式/控制流程,因此这项任务并不容易。

1。拉方法(文件轮询)

假设有一个辅助程序(类型1)处理显示CAPTCHA,接收输入并使用CAPTCHA输入写入文本文件。 CasperJS可以处理的就是将CAPTCHA屏幕截图写入磁盘并等待带有“已解析”文本的文件。

var fs = require("fs"),
    captchaFile = "cfile.png",
    parsedFile = "pfile.txt";
casper.waitForCaptcha = function(captchaFile, parsedFile){
    casper.then(function(){
        this.captureSelector(captchaFile, "someSelectorOfTheCaptcha");
    });
    casper.waitFor(function check(){
        return fs.exists(parsedFile);
    }, function then(){
        // do something on time
        // check if correct...
        if (!correct) {
            fs.remove(captchaFile);
            fs.remove(parsedFile);
            this.waitForCaptcha(captchaFile, parsedFile);
            // Problem: the secondary process needs to sense that a new CAPTCHA is presented
        }
    }, function onTimeout(){
        // do something when failed
    }, 60000); // 1min should suffice as a timeout
    return this;
};
casper.start(url).waitForCaptcha(captchaFile, parsedFile).run();

此代码假定您要在CAPTCHA错误时重试,但如果没有解码文件故意传递分钟则不会。这是一个拉取过程,通过轮询文件是否已经存在。

2。推进方法

也可以使用推送过程,其中辅助程序(类型2)使用PhantomJS webserver module向CasperJS进程发送请求。因为将存在两个并发控制流,所以CasperJS部分需要等待很长时间,但是一旦收到带有解码字的请求,就可以用unwait打破等待。

var server = require('webserver').create(),
    fs = require("fs"),
    captchaFile = "cfile.png";

function neverendingWait(){
    this.wait(5000, neverendingWait);
}

casper.checkCaptcha = function(captchaFile, phantomPort, secondaryPort){
    // here the CAPTCHA is saved to disk but it can also be set directly if captured through casper.captureBase64
    this.captureSelector(captchaFile, "someSelectorOfTheCaptcha");

    // send request to the secondary program from the page context
    this.evaluate(function(file){
        __utils__.sendAJAX("http://localhost:"+secondaryPort+"/", "POST", {file: file}, true);
    }, captchaFile);

    // start the server to receive solved CAPTCHAs
    server.listen(phantomPort, {
       'keepAlive': true
    }, function (request, response) {
        console.log('Request received at ' + new Date());
        if (request.post) { // is there a response?
            this.then(function(){
                // check if it is correct by reading request.post ...
                if (!correct){
                    response.statusCode = 404;
                    response.headers = {
                        'Cache': 'no-cache',
                        'Content-Type': 'text/plain;charset=utf-8'
                    };
                    response.close();
                    server.close();
                    this.checkCaptcha(captchaFile, phantomPort, secondaryPort);
                } else {
                    response.statusCode = 200;
                    response.headers = {
                        'Cache': 'no-cache',
                        'Content-Type': 'text/plain;charset=utf-8'
                    };
                    response.close();
                    server.close();
                    this.unwait(); // abort the neverendingWait
                }
            });
        } else {
            response.statusCode = 404;
            response.headers = {
              'Cache': 'no-cache',
              'Content-Type': 'text/plain;charset=utf-8'
            };
            response.close();
            server.close();
            this.checkCaptcha(captchaFile, phantomPort, secondaryPort);
        }
    });
    return this;
};

casper.start(url).then(function(){
    this.checkCaptcha(captchaFile, 8080, 8081);
}).then(neverendingWait).then(function(){
    // Do something here when the captcha is successful
}).run();