CasperJS 无法设置 window.navigator 对象

Pra*_*nth 2 javascript headless-browser phantomjs casperjs

尝试使用 CasperJS 抓取网页。网页会检查浏览器是否为 IE 6/7。

使用 casperjs 传递 userAgent 似乎不满足其条件。UserAgent 通过:Mozilla/4.0(兼容;MSIE 6.0;Windows NT 5.1) 以下是页面进行的检查以确定浏览器

agt = navigator.userAgent.toLowerCase();
browserType = navigator.appName;

if( ((browserType.indexOf("xplorer") != -1) 
    && (agt.indexOf("msie 6.") != -1))
    ||  ((browserType.indexOf("xplorer") != -1) 
    && (agt.indexOf("msie 7.") != -1)) )
{

}
else
{
    alert("This "+ browserType + " Version is not supported by this application. Please use Internet Explorer  6.x or Internet Explorer 7.x.");
    window.close();
}
Run Code Online (Sandbox Code Playgroud)

以下是来自 casperjs 的调试信息。

[info] [remote] [alert] 此应用程序不支持此 Netscape 版本。请使用 Internet Explorer 6.x 或 Internet Explorer 7.x。

[警告] [幻影] 加载资源失败,状态=失败(HTTP 200):http://

window.navigator在页面重定向之前设置对象的任何指针?

Art*_* B. 5

这些navigator属性是只读的,所以你不能设置它们,而且 PhantomJS 不提供设置它的能力。

解决方案是制作navigator对象的代理。旧的navigator留在后台,但它被一个行为相同的新的取代,但带有appName“Internet Explorer”。整个引导过程可以从page.initialized回调中触发。

casper.on('page.initialized', function(){
    this.evaluate(function(){
        (function(oldNav){
            var newNav = {};
            [].forEach.call(Object.getOwnPropertyNames(navigator), function(prop){
                if (prop === 'appName') {
                    Object.defineProperty(newNav, prop, {
                        enumerable: false,
                        configurable: false,
                        writable: false,
                        value: 'Internet Explorer'
                    });
                } else {
                    Object.defineProperty(newNav, prop, {
                        enumerable: false,
                        configurable: false,
                        get: function(){
                            return oldNav[prop];
                        }
                    });
                }
            });
            window.navigator = newNav;
        })(window.navigator);
    });
});
Run Code Online (Sandbox Code Playgroud)

带有page.onInitialized事件处理程序的vanilla PhantomJS 也是如此。

绕过浏览器检测并不能保证页面在 PhantomJS 上工作或看起来不错。有些页面针对 IE 进行了“优化”是有原因的,原因是大多数时候使用了其他浏览器中没有的一些专有功能。