PhantomJS 模拟登录二

以下的模拟登录程序,流程跟直接操作浏览器一致,不相同的地方是一个是程序开做,一个是人来做。

"use strict";
var page = require('webpage').create();

page.onResourceRequested = function (req) {
    //console.log('requested: ' + JSON.stringify(req, undefined, 4));
};
page.onResourceReceived = function (res) {
    //console.log('received: ' + JSON.stringify(res, undefined, 4));
};
page.onConsoleMessage = function(message) {
    console.log(message);
};


// 访问需要登录的页面
var url = 'http://my.sandbox.ebay.com/ws/eBayISAPI.dll?MyEbay&gbh=1&CurrentPage=MyeBayAllSelling&ssPageName=STRK:ME:LNLK:MESX';

page.open(url, function (status) {  
    if (status === 'success') {
        page.includeJs("http://xxx:8888/js/jquery.min.js", function() {
           var res = page.evaluate(function() {
                var str = '';
                $("table.my_itl-iT tr.my_itl-itR td a.g-asm").each(function(){
                    str += $(this).text()+"\n";
                });
                return str;
           });
           
           console.log(res);
            
           phantom.exit();
        });
    } else {
        phantom.exit();
    }
});

/*
page.open('https://signin.sandbox.ebay.com/ws/eBayISAPI.dll', function (status) {
    if (status === 'success') {
        page.includeJs("http:/xxx:8888/js/jquery.min.js", function() {
            // evaluate里面是一个沙箱,主要的DOM操作地
            page.evaluate(function() {
                var form = $("#SignInForm");
                form.find("input[name=userid]").val("testuser_xxx");
                form.find("input[name=pass]").val("xxxx");
                
                form.trigger("submit");
            });
            // 等待5秒后收集结果
            window.setTimeout(function() {
                //console.log(page.content);
                
                var cookies = page.cookies;
                var saveData = '';
                for(var i in cookies) {
                    console.log(cookies[i].name + '=+' + cookies[i].value);
                    saveData += cookies[i].name+"="+cookies[i].value+"&";
                }
    
                // 1 
                // 如果供外部程序使用,这里把cookie送出
                var save = webpage.create();
                save.open('http://xxx:7070/i.php', 'POST', saveData, function (status) {
                    if (status === "success") {
                        console.log(save.content);
                    }
                    phantom.exit();
                });
                // 2 
                // 如果不需要供外部使用,成功登录后直接退出记录
                // Cookie记录到文件,这样仅需要在Cookie失效时重新登录即可
                // phantom.exit();
            }, 5000);
        });
    } else {
        phantom.exit();
    }
});
*/

登录成功后,需要访问登录保护的页,可以把Cookie发出出去,然后外部程序来完成,也可以继续让PhantomJs去访问,如果抓取内容不连续,那么就类似于用完后,关闭浏览器,下次用再次打开浏览器,载入浏览器是低效的,而且它会载入URL相关的所有页,所以应该使用外部程序完成抓取,程序一旦检测到Cookie失效(比如检测到了跳到登录页),那么马上启动浏览器,重新自动登录,然后取到最新Cookie,这个类似于数据库链接里面的断线重连,如果断线重连无法链接,那么就需要终止了。 需要注意的是PhantomJs并不会把会话Cookie写入到你指定的cookie文件,会话cookie仅在phantom存在时有效,这个跟真实浏览器一致,浏览器关闭,所有会话Cookie会被删除,因为会话cookie的过期时间为0,意味关闭则失效,所以如果这些会话Cookie是维持登录状态的,就需要主动发送出去或记录,而不能依赖cookie文件。

用一个真实的浏览器去登录,再牛逼的防机器登录机制都无效(不使用验证码的情况,防程序登录的机制无非是用JS产生Cookie, 在HTML渲染后根据环境动态添加表单域,这些在一般模拟登录中,几乎可以通杀,因为你不可能得到HTML渲染后的值,也取不到JS在客户端产生的Cookie)。