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

Jus*_*ner 7 javascript captcha automation phantomjs casperjs

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

Art*_* B. 12

由于与PhantomJS相比CasperJS的结构化/控制流程,这样的任务并不容易.

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();
Run Code Online (Sandbox Code Playgroud)

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

2.推动方法

在辅助程序(类型2)通过利用PhantomJS网络服务器模块向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();
Run Code Online (Sandbox Code Playgroud)