【问题标题】:How to stop CasperJS execution and let the user input some value and then continue to execute?如何停止 CasperJS 执行并让用户输入一些值然后继续执行?
【发布时间】:2014-12-20 18:07:51
【问题描述】:

我正在使用 PhantomJSCasperJS 来自动化我的一些任务。在其中一项任务中,我需要手动提供验证码字符串,然后才能实际处理该任务。对于这个问题,我能想到的就是截取网页的截图,然后手动检查截取的图片,并将验证码字符串保存到文本文件中。之后,我可以使用 CasperJS 中的 file system 模块来读取该值并继续执行该过程。我想知道执行此类任务的最佳方法是什么。

【问题讨论】:

    标签: javascript automation phantomjs captcha casperjs


    【解决方案1】:

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

    1。拉取方式(文件轮询)

    假设有一个辅助程序(类型 1)处理显示验证码、接收输入并使用验证码输入写入文本文件。 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();
    

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

    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();
    

    【讨论】:

    • @Yousui 如果您有兴趣,我可以尝试充实推送方法,但我从未真正使用过 webserver 模块,更不用说 CasperJS 了。
    • 是的 Artjom。如果你能提供一个骨架,那将非常有帮助。谢谢。
    • 我为推送方法添加了一些代码,但我没有尝试。不过它应该可以工作。
    • 谢谢Artjom。我去看看。
    猜你喜欢
    • 1970-01-01
    • 2017-04-14
    • 2020-08-26
    • 2011-12-10
    • 2020-03-28
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多