spider.js chrome扩展

2021-07-06  本文已影响0人  LCSan
spider = function(e){
    this.ele = e || document;
}
spider.prototype.$x = function(xpath){
    var res = this.get(function(pr){
        var doc = (pr && pr.ownerDocument) || document;
        var result = doc.evaluate(xpath, pr || doc, null, XPathResult.ANY_TYPE, null);
        switch (result.resultType) {
        case XPathResult.NUMBER_TYPE:
            return result.numberValue;
        case XPathResult.STRING_TYPE:
            return result.stringValue;
        case XPathResult.BOOLEAN_TYPE:
            return result.booleanValue;
        default:
            var nodes = [];
            var node;
            while (node = result.iterateNext()){
                nodes.push(node);
            }
            return nodes;
        }
    });
    return new spider(res);
}
spider.prototype.$ = function(css, ext){
    var res = this.get(function(pr){
        var doc = (pr && pr.contentDocument) || pr || document;
        var temp = [];
        doc.querySelectorAll(css).forEach(function(item){
            if(ext){
                var res;
                try{
                    res = eval(`item.${ext}`);
                }catch(err){
                    res = eval(`item${ext}`);
                }
                temp.push(res);
            }else{
                temp.push(item);
            }
        });
        return temp;
    });
    return new spider(res);
}
spider.prototype.$j = function jsonPath(expr, arg) {
   var P = {
      resultType: arg && arg.resultType || "VALUE",
      result: [],
      normalize: function(expr) {
         var subx = [];
         return expr.replace(/[\['](\??\(.*?\))[\]']/g, function($0,$1){return "[#"+(subx.push($1)-1)+"]";})
                    .replace(/'?\.'?|\['?/g, ";")
                    .replace(/;;;|;;/g, ";..;")
                    .replace(/;$|'?\]|'$/g, "")
                    .replace(/#([0-9]+)/g, function($0,$1){return subx[$1];});
      },
      asPath: function(path) {
         var x = path.split(";"), p = "$";
         for (var i=1,n=x.length; i<n; i++)
            p += /^[0-9*]+$/.test(x[i]) ? ("["+x[i]+"]") : ("['"+x[i]+"']");
         return p;
      },
      store: function(p, v) {
         if (p) P.result[P.result.length] = P.resultType == "PATH" ? P.asPath(p) : v;
         return !!p;
      },
      trace: function(expr, val, path) {
         if (expr) {
            var x = expr.split(";"), loc = x.shift();
            x = x.join(";");
            if (val && val.hasOwnProperty(loc))
               P.trace(x, val[loc], path + ";" + loc);
            else if (loc === "*")
               P.walk(loc, x, val, path, function(m,l,x,v,p) { P.trace(m+";"+x,v,p); });
            else if (loc === "..") {
               P.trace(x, val, path);
               P.walk(loc, x, val, path, function(m,l,x,v,p) { typeof v[m] === "object" && P.trace("..;"+x,v[m],p+";"+m); });
            }
            else if (/,/.test(loc)) { // [name1,name2,...]
               for (var s=loc.split(/'?,'?/),i=0,n=s.length; i<n; i++)
                  P.trace(s[i]+";"+x, val, path);
            }
            else if (/^\(.*?\)$/.test(loc)) // [(expr)]
               P.trace(P.eval(loc, val, path.substr(path.lastIndexOf(";")+1))+";"+x, val, path);
            else if (/^\?\(.*?\)$/.test(loc)) // [?(expr)]
               P.walk(loc, x, val, path, function(m,l,x,v,p) { if (P.eval(l.replace(/^\?\((.*?)\)$/,"$1"),v[m],m)) P.trace(m+";"+x,v,p); });
            else if (/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(loc)) // [start:end:step]  phyton slice syntax
               P.slice(loc, x, val, path);
         }
         else
            P.store(path, val);
      },
      walk: function(loc, expr, val, path, f) {
         if (val instanceof Array) {
            for (var i=0,n=val.length; i<n; i++)
               if (i in val)
                  f(i,loc,expr,val,path);
         }
         else if (typeof val === "object") {
            for (var m in val)
               if (val.hasOwnProperty(m))
                  f(m,loc,expr,val,path);
         }
      },
      slice: function(loc, expr, val, path) {
         if (val instanceof Array) {
            var len=val.length, start=0, end=len, step=1;
            loc.replace(/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/g, function($0,$1,$2,$3){start=parseInt($1||start);end=parseInt($2||end);step=parseInt($3||step);});
            start = (start < 0) ? Math.max(0,start+len) : Math.min(len,start);
            end   = (end < 0)   ? Math.max(0,end+len)   : Math.min(len,end);
            for (var i=start; i<end; i+=step)
               P.trace(i+";"+expr, val, path);
         }
      },
      eval: function(x, _v, _vname) {
         try { return $ && _v && eval(x.replace(/@/g, "_v")); }
         catch(e) { throw new SyntaxError("jsonPath: " + e.message + ": " + x.replace(/@/g, "_v").replace(/\^/g, "_a")); }
      }
   };


    var res = this.get(function(pr){        
        var $ = pr;
        $ = $.constructor == Object ? $ : JSON.parse($);
        if (expr && $ && (P.resultType == "VALUE" || P.resultType == "PATH")) {
            P.trace(P.normalize(expr).replace(/^\$;/,""), $, "$");
            return P.result;
        }
        return pr;
    });
    return new spider(res);
} 

spider.prototype.filter = function(reg, ext){
    var res = this.get(function(pr){
        var ag = spider.prototype.str(pr,ext);
        if(reg.test(ag)){
            return pr;
        }
        return false;
    });
    return new spider(res);
}
spider.prototype.replace = function(reg, toScp, ext){
    var res = this.get(function(pr){
        var ag = spider.prototype.str(pr,ext);
        return ag.replace(reg, toScp);
    });
    return new spider(res);
}
spider.prototype.split = function(reg, ext){
    var res = this.get(function(pr){
        var ag = spider.prototype.str(pr,ext);
        return ag.split(reg);
    });
    return new spider(res);
}
spider.prototype.regex = function(reg, ext){
    var res = this.get(function(pr){
        var ag = spider.prototype.str(pr,ext);
        var re = ag.match(reg);
        re = (re && re.length>1) ? re.slice(1) : re;
        return re;
    });
    return new spider(res);
}
spider.prototype.mix = function(expression) {
    return eval(`this.${expression}`)
}
spider.prototype.str = function(t,ext){
    if(!t){
        return;
    }
    if(t.constructor == Array || t.constructor == Object){
        for(i in t){
            t[i] = this.str(t[i],ext);
        }
        if(t.constructor == Array && t.length == 1 && t[0].constructor != Array){
            return t[0];
        }
        return t;
    }
    if(ext){
        var res;
        try{
            res = eval(`t.${ext}`);
        }catch(err){
            res = eval(`t${ext}`);
        }
        return res;
    }
    if(t.nodeType){
        switch (t.nodeType){
        case Node.ELEMENT_NODE:
            // 1 元素
            return t.outerHTML;
        default:
            return t.value || t.nodeValue;
        }
    }
    return t;
}
spider.prototype.get = function(callback){
    if(!this.ele){
        return;
    }
    if(this.ele.constructor == Array){
        var res = [];
        for(item in this.ele){
            re = callback ? callback(this.ele[item]) : this.ele[item];
            if(re){
                if(re.constructor == Array){
                    res = res.concat(re);
                }else{
                    res.push(re);
                }
            }
        }
        return res;
    }
    var re = callback ? callback(this.ele) : this.ele;
    return re;
}
spider.prototype.re = function(ext){
    var re = this.get(function(pr){
        return spider.prototype.str(pr,ext);
    });
    if(re.constructor == Array && re.length == 1){
        return re[0];
    }
    return re;
}
spider.prototype.json = function(ext){
    return JSON.stringify(this.re(ext));
}
spider.prototype.more = function(exps, tip) {
    if(exps.constructor == Array || exps.constructor == Object){
        // 处理表达式
        exps.forEach(function(a,b,c){
            if(a.constructor == Array){
                a.forEach(function(a1,b1,c1){
                    c1[b1]=`'${a1.replace(/'/ig,"\\'")}'`;
                });
                c[b] = `t.${tip.toLowerCase()}(${a.join(",")})`;
            }else{
                c[b] = `t.${tip.toLowerCase()}('${a.replace(/'/ig,"\\'")}')`;
            }
        });
        var res = this.get(function(pr){
            var t = new spider(pr);
            var temp = exps.constructor == Object ? {} : [];
            for(i in exps){
                var exp = eval(exps[i]);
                if(exp.constructor == spider){
                    exp = exp.ele;
                }
                temp[i] = exp;
            }
            if(exps.constructor == Array){
                temp = [[temp]];
            }
            return temp;
        });
        return new spider(res);
    }
    return this;
}
上一篇下一篇

猜你喜欢

热点阅读