脱浏览器环境脚本-补环境利器

//获取原型环境代码
let getProtoEnvCode = function getProtoEnvCode(proto,instanceObj) {
    //proto:原型函数 
    //instanceObj:实例对象,可选参数 传的话会添加默认值
    let code = "";
    let protoName = proto.name;
    //添加注释
    code += `// ${protoName}对象\r\n`;
    //定义原型
    code += `${protoName} = function ${protoName}(){`;
    try {
        new proto;
    } catch (e) {
        code += `return ldvm.toolsFunc.throwError('${e.name}','${e.message}');`;
    }

    code += `}\r\n`;
    //保护原型
    code += `ldvm.toolsFunc.safeProto(${protoName},"${protoName}");\r\n`;
    //设置原型链
    let protoObj = proto.prototype;
    let proto_protoName = Object.getPrototypeOf(protoObj)[Symbol.toStringTag];//原型对象的原型的名称,父级原型名称
    if(proto_protoName !== undefined){//在存在父级的情况下设置原型
        code += `Object.setPrototypeOf(${protoName}.prototype,${proto_protoName}.prototype);\r\n`;
    }

    //设置原型属性
    for(const key in Object.getOwnPropertyDescriptors(proto)){
        if(key === "arguments" || key === "caller" || key === "length" || key === "name" || key === "prototype"){
            continue;
        }
        let descriptor = getDescriptor(proto,key,protoName,protoName,instanceObj);
        code += `ldvm.toolsFunc.defineProperty(${protoName},"${key}",${descriptor});\r\n`;
    }
    //设置原型对象的属性
    for(const key in Object.getOwnPropertyDescriptors(proto.prototype)){
        if(key === "constructor"){
            continue;
        }
        let descriptor = getDescriptor(proto.prototype,key,`${protoName}.prototype`,protoName,instanceObj);
        code += `ldvm.toolsFunc.defineProperty(${protoName}.prototype,"${key}",${descriptor});\r\n`;
    }
    
    console.log(code);
    copy(code);
    //return code;
}

//获取实例对象的环境代码
let getObjEnvCode = function getObjEnvCode(obj,objName,instanceObj){
    //obj 实例对象
    //objName 实例对象名称
    //instanceObj 实例对象 传输的话设置默认值
    let code = "";
    //添加注释
    code += `// ${objName}对象\r\n`;
    //定义对象
    code += `${objName} = {}\r\n`;
    //设置原型
    let protoName = Object.getPrototypeOf(obj)[Symbol.toStringTag];
    if(protoName != undefined){
        code += `Object.setPrototypeOf(${objName},${protoName}.prototype);\r\n`;
    }

    //设置对象属性
    for(const key in Object.getOwnPropertyDescriptors(obj)){
        let descriptor = getDescriptor(obj,key,objName,objName,instanceObj);
        code += `ldvm.toolsFunc.defineProperty(${objName},"${key}",${descriptor});\r\n`;
    }

    console.log(code);
    copy(code);
    //return code;
}

//获取属性描述符
let getDescriptor = function getDescriptor(obj,prop,objName,protoName,instanceObj) {
    let descriptor = Object.getOwnPropertyDescriptor(obj,prop);
    let configurable = descriptor.configurable;
    let enumerable = descriptor.enumerable;
    let code = `{configurable:${configurable}, enumerable:${enumerable}, `;
    if(descriptor.hasOwnProperty("writable")){
        let writable = descriptor.writable;
        code += `writable:${writable}, `;
    }
    if(descriptor.hasOwnProperty("value")){
        let value = descriptor.value;
        if(value instanceof Object){
            if(typeof value === "function"){
                 code += `value:function(){return ldvm.toolsFunc.dispatch(this,${objName},"${protoName}","${prop}",arguments);}`;
                
            }else{
                //需要关注
                console.log("需要额外关注",value);
                //JSON.stringify(value)//如果不是非循环引用可以这样转化值
                code = `value:{}`;
            }
        }else if(typeof value === "symbol"){
             code += `value:${value.toString()}`;
        }else if(typeof value === "string"){
            code += `value:"${value}"`;
        }else{
            code += `value:${value}`;
        }
    }

    if(descriptor.hasOwnProperty("get")){//有默认值
        let get = descriptor.get;
        if(typeof get === "function"){
            let defaultValue;
            try{
                defaultValue = get.call(instanceObj);//获取属性值 Object.getOwnPropertyDescriptor(window,'name').get.call(window)
            }catch(e){
                 
            }

            if(defaultValue == undefined || defaultValue instanceof Object){
               code += `get:function(){return ldvm.toolsFunc.dispatch(this,${objName},"${protoName}","${prop}_get",arguments);}, `;
            }else{
                if(typeof defaultValue === 'string'){
                    code += `get:function(){return ldvm.toolsFunc.dispatch(this,${objName},"${protoName}","${prop}_get",arguments,'${defaultValue}');}, `;
                }else if(typeof value === "symbol"){
                    code += `get:function(){return ldvm.toolsFunc.dispatch(this,${objName},"${protoName}","${prop}_get",arguments,${defaultValue.toString()});}, `;
                }else{
                    code += `get:function(){return ldvm.toolsFunc.dispatch(this,${objName},"${protoName}","${prop}_get",arguments,${defaultValue});}, `;
                }
            }
           
        }else{
            code += `get:undefined, `;
        }
    }

    if(descriptor.hasOwnProperty("set")){//没有默认值
        let set = descriptor.set;
        if(typeof set === "function"){
            code += `set:function(){return ldvm.toolsFunc.dispatch(this,${objName},"${protoName}","${prop}_set",arguments);}`;
        }else{
            code += `set:undefined`;
        }
    }

    code += "}";
    return code;
}



//getProtoEnvCode(Window);
//getObjEnvCode(window,"window")

补充代码

 //定义对象属性defineProperty
    ldvm.toolsFunc.defineProperty = function defineProperty(obj,prop,oldDescriptor){
        let newDescriptor = {};//新的构造器
        newDescriptor.configurable = ldvm.config.proxy || oldDescriptor.configurable;//如果开启代理必须是true,如果对象的configurable是false,不能被proxy代理
        newDescriptor.enumerable = oldDescriptor.enumerable;
        if(oldDescriptor.hasOwnProperty("writable")){
            newDescriptor.writable =  ldvm.config.proxy || oldDescriptor.writable;//如果开启代理必须是true
        }
        if(oldDescriptor.hasOwnProperty("value")){
            let value = oldDescriptor.value;
            if(typeof value === "function"){
                ldvm.toolsFunc.safeFunc(value,prop);
            }
            newDescriptor.value = value;
        }
        if(oldDescriptor.hasOwnProperty("get")){
            let get = oldDescriptor.get;
            if(typeof get === "function"){
                ldvm.toolsFunc.safeFunc(get,`get ${prop}`);
            }
            newDescriptor.get = get;
        }
        if(oldDescriptor.hasOwnProperty("set")){
            let set = oldDescriptor.set;
            if(typeof set === "function"){
                ldvm.toolsFunc.safeFunc(set,`set ${prop}`);
            }
            newDescriptor.set = set;
        }
        Object.defineProperty(obj,prop,newDescriptor);
    }

在补环境时,浏览器对象属性如此之多,每次一个一个手工补是不是很繁琐,这种情况使用自动脱浏览器环境就方便了,可以自动生成补环境代码放到自己项目里,这样就能省去大量人工工作。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
火车浏览器不是一个普通的浏览器,它是一个可视化的自动脚本采集工具软件。软件可以读取写入mysql,sqlserver,sqlite,access四种数据库,可以通过设置脚本,达到自动登录,识别验证码,自动抓取数据,自动提交数据,点击网页,下载文件,操作数据库,收发邮件等操作。还可以使用逻辑操作,完成判断,循环,跳转等操作。软件界面美观简洁、使用方便,速度快,质量高,对于用户来说是一款很不错的软件,小编这里推荐大家使用这款软件! 火车浏览器功能特色 1、可视化操作 操作简单,完全可视化图形操作,无需专业IT人员。操作的内容是浏览器处理过的内容,jax,瀑布流之类的采集非常简单,一些js加密的数据也能轻易得到,不需要抓取数据包分析。 2、自定义流程 完全自定义采集流程。打开网页,输入数据,提取数据,点击网页上的元素,操作数据库,验证码识别,抓取循环记录,处理列表,条件判断,完全自定义流程,采集就像是搭积木,功能自由组合。 3、自动打码 采集速度快,程序注重采集效率,页面解析速度飞快,不需要访问的页面或广告之类可以直接屏蔽,加快访问速度。 4、生成EXE 不只是个采集器,更是营销利器。不光能采集数据保存到数据库或其它地方,还可以群发现有的数据到各个网站。可以做到自动登录,自动识别验证码,是万能的浏览器。 5、项目管理 利用解决方案可以直接生成单个应用程序。单个程序可以离火车浏览器并运行,官方提供了一个软件管理平台,用户可以进行授权等管理。每个用户都是开发者,每个人都能从平台中获利。 火车浏览器截图

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liberty888

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值