爬取美拍视频网址

1)博主最近想写一个类似小视频的webApp项目

爬取美拍的时候发现竟然找不到video标签,这样就影响了我获取视频地址啊
仔细看看网页源码发现发现原来视频地址藏在元素身上了

image.png

但是这个视频地址是加密了的?怎么办?看看美拍的请求,发现解密方法藏在js中,也就是说 解密是靠前端解密的

 var d = a("jquery")
      , e = a("support")
      , f = a("constants")
      , g = a("base64")
      , h = "substring"
      , i = "split"
      , j = "replace"
      , k = "substr";
    b.decodeMp4 = {
        getHex: function(a) {
            return {
                str: a[h](4),
                hex: a[h](0, 4)[i]("").reverse().join("")
            }
        },
        getDec: function(a) {
            var b = parseInt(a, 16).toString();
            return {
                pre: b[h](0, 2)[i](""),
                tail: b[h](2)[i]("")
            }
        },
        substr: function(a, b) {
            var c = a[h](0, b[0])
              , d = a[k](b[0], b[1]);
            return c + a[h](b[0])[j](d, "")
        },
        getPos: function(a, b) {
            return b[0] = a.length - b[0] - b[1],
            b
        },
        decode: function(a) {
            var b = this.getHex(a)
              , c = this.getDec(b.hex)
              , d = this[k](b.str, c.pre);
            return g.atob(this[k](d, this.getPos(d, c.tail)))
        }
    };

后期经过加工改造

;(function(base64){
        var substring='substring',
            split='split',
            reverse='reverse',
            join='join',
            toString='toString',
            substr='substr',
            replace='replace',
            fn={
            getHex: function(str) {//获取前4位标记数字
                return {
                    str: str[substring](4),//排除前4位字符串
                    hex: str[substring](0, 4)[split]("")[reverse]()[join]("")//前4位倒序
                }
            },
            getDec: function(str) {//获取混淆字符位置坐标
                str = parseInt(str, 16)[toString]();//前4位倒序的16进制
                //str[substring](0, 2)[split]("");
                return {
                    pre: str[substring](0, 2)[split](""),//前面坐标
                    tail: str[substring](2)[split]("")//后面坐标
                }
            },
            delStr: function(str, pos) {//混淆的字符抽取
                var s = str[substring](0, pos[0]),
                    del = str[substr](pos[0], pos[1]);//需替换的字符
                return s + str[substring](pos[0])[replace](del, "");//返回替换完成后的base64字符串
            },
            getPos: function(str, pos) {
                return [str.length - pos[0] - pos[1],pos[1]];
            },
            decode: function(str) {//解密
                var sh = this.getHex(str),//获取前4位标记数字
                    pos = this.getDec(sh.hex),//获取混淆位置坐标
                    d = this.delStr(sh.str, pos.pre);//前面混淆的字符抽取
                    d=this.delStr(d, this.getPos(d, pos.tail));
                return decodeURIComponent(escape(this.atob(d)));//base64转成utf-8(兼容中文)  atob
            },
            encode:function(str){//加密
                var base64=this.btoa(unescape(encodeURIComponent(str))),//转换成base64格式
                    random=this.getRanNum(base64),//获取16进制是4位数的随机字符
                    pos = this.getDec(random);//获取混淆位置坐标
                base64 = this.addStr(base64, pos);//插入混淆字符
                //console.log(random,pos)
                return random[toString]()[split]("")[reverse]()[join]("")+base64;
            },
            addStr: function(str, pos) {//混淆的字符插入
                var r1=this.getRanStr(pos.pre[1]),//获取随机字符串(前)
                    r2=this.getRanStr(pos.tail[1]),//获取随机字符串(后)
                    pre=this.insertStr(str,r1,pos.pre[0]),//插入随机字符串(前)
                    tail=pre.length - pos.tail[0];
                str=this.insertStr(pre,r2,tail);//插入随机字符串(后)
                return str;
            },
            atob:function(src){//解密
                //用一个数组来存放解码后的字符。
                var str=new Array();
                var ch1, ch2, ch3, ch4;
                var pos=0;
                //过滤非法字符,并去掉'='。
                src=src.replace(/[^A-Za-z0-9\+\/]/g, '');
                //decode the source string in partition of per four characters.
                while(pos+4<=src.length){
                  ch1=this.deKey[src.charCodeAt(pos++)];
                  ch2=this.deKey[src.charCodeAt(pos++)];
                  ch3=this.deKey[src.charCodeAt(pos++)];
                  ch4=this.deKey[src.charCodeAt(pos++)];
                  str.push(String.fromCharCode(
                    (ch1<<2&0xff)+(ch2>>4), (ch2<<4&0xff)+(ch3>>2), (ch3<<6&0xff)+ch4));
                }
                //给剩下的字符进行解码。
                if(pos+1<src.length){
                  ch1=this.deKey[src.charCodeAt(pos++)];
                  ch2=this.deKey[src.charCodeAt(pos++)];
                  if(pos<src.length){
                    ch3=this.deKey[src.charCodeAt(pos)];
                    str.push(String.fromCharCode((ch1<<2&0xff)+(ch2>>4), (ch2<<4&0xff)+(ch3>>2)));
                  }else{
                    str.push(String.fromCharCode((ch1<<2&0xff)+(ch2>>4)));
                  }
                }
                //组合各解码后的字符,连成一个字符串。
                return str.join('');
            },
            btoa:function(src){//加密
                //用一个数组来存放编码后的字符,效率比用字符串相加高很多。
                var str=new Array();
                var ch1, ch2, ch3;
                var pos=0;
                //每三个字符进行编码。
                while(pos+3<=src.length){
                  ch1=src.charCodeAt(pos++);
                  ch2=src.charCodeAt(pos++);
                  ch3=src.charCodeAt(pos++);
                  str.push(this.enKey.charAt(ch1>>2), this.enKey.charAt(((ch1<<4)+(ch2>>4))&0x3f));
                  str.push(this.enKey.charAt(((ch2<<2)+(ch3>>6))&0x3f), this.enKey.charAt(ch3&0x3f));
                }
                //给剩下的字符进行编码。
                if(pos<src.length){
                  ch1=src.charCodeAt(pos++);
                  str.push(this.enKey.charAt(ch1>>2));
                  if(pos<src.length){
                    ch2=src.charCodeAt(pos);
                    str.push(this.enKey.charAt(((ch1<<4)+(ch2>>4))&0x3f));
                    str.push(this.enKey.charAt(ch2<<2&0x3f), '=');
                  }else{
                    str.push(this.enKey.charAt(ch1<<4&0x3f), '==');
                  }
                }
                //组合各编码后的字符,连成一个字符串。
                return str.join('');
            },
            insertStr:function(str,addstr,pos){//往指定位置插入字符串
                return str[substring](0,pos)+addstr+str[substring](pos);
            },
            getRanNum:function(str){//获取16进制是4位数的4位随机字符
                var ranArr=[];
                ;(function(){
                    var n='',
                        length=str.length;
                    /** 4101开始16进制是4位数 **/
                    for(var i=4101;i<=9999;i++){//找出所有符合要求的16进制4位数
                        n=i[toString](16);//10转成16
                        if(length>=8&&!(Math.floor(i/100)%10===0||i%10===0)&&n.length===4){
                        //正常的base64编码长度大于8才前后加混淆字符
                            //console.log(i,n);
                            if(Math.floor(i/1000)<=length/2&&Math.floor(i%100/10)<=length/2){//混淆位置不能大于长度一半
                                ranArr.push(n);
                            }
                        }else if(i%100===0&&n.length===4){//只在前面插入混淆字符
                            if(Math.floor(i/1000)<=length){//混淆位置不能大于长度
                                ranArr.push(n);
                            }
                        }
                    }
                }());
                var length=ranArr.length,
                    ran = Math.round(Math.random()*(length-1));
                return ranArr[ran];
            },
            enKey:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
            deKey: new Array(
                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
                52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
                -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
                15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
                -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
                41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
            ),
            getRanStr:function(num){//获取指定个数随机字符串
                var key=this.enKey.split("");
                    length=key.length,
                    res = "";
                 for(; num-- ;) {
                     var id = Math.round(Math.random()*(length-1));
                     res += key[id];
                 }
                 return res;
            }
        }
        base64.tranCode=fn;
        window.base64=base64;
    }(window.base64||{}));

此方法包括 解密以及加密
window.base64.tranCode.decode(str) //解密

image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349

推荐阅读更多精彩内容

  • /**ios常见的几种加密方法: 普通的加密方法是讲密码进行加密后保存到用户偏好设置( [NSUserDefaul...
    彬至睢阳阅读 2,917评论 0 7
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,339评论 8 265
  • 今天是12月份的第一天,在30号即将结束的时候,原本计划的月度总结没有按计划进行。 今天是我离开简书更新文字的第2...
    郝跳舞阅读 173评论 0 0
  • 少女时代觉得婚姻是相濡以沫,相互理解,共同进步,互相陪伴,处处体贴,并且,坚信永恒。转眼,宝宝快三岁,烟火气灼掉曾...
    想要一直走在路上阅读 170评论 0 1
  • 时间是黑色的。 只有在夜里 当所有的喧嚣散尽, 光华退去 我的灵魂才能回归躯体 我白日里所做的一切 都是为了这一刻...
    张庆朋阅读 241评论 0 0