文书网vl5x值的计算

爬文书网是件痛苦的事,不光要应对各种反爬技术,更要忍受极慢的响应速度,黎明前的黑暗总是漫长的,在你快要放弃的时候你就成功了。

最近有个项目要爬文书网的部分判决文书,由于这个网站用了一些反爬技术,而且网页打开非常慢,用PhantomJS来爬的话效率太低,只能另辟蹊径了。
分析网页的http数据包,发现ListContent返回的JSON数据里有文书的ID,案件名称,裁判日期等需要爬取的关键信息,也就是说通过Requests的post请求直接访问后台的URL就可以获取想要的数据了。
然而post data里的vl5x是绕不开的槛
这里写图片描述
找一个浏览器里已经用过的vl5x去post ListContent,返回的是remind key,因此这个vl5x值是实时计算生成的。
到底这个值是怎么计算的呢,既然浏览器能算出vl5x的值,那算法应该隐藏在网页的JS文件中。好吧,继续找,在Lawyee.CPWSW.List.js文件里找到了这段

            $.ajax({
                url: "/List/ListContent",
                type: "POST",
                async: true,
                data: { "Param": listparam, "Index": index, "Page": page, "Order": order, "Direction": direction, "vl5x": getKey(), "number": yzm1, "guid": guid1 },
                success: function (data) {
                    //datalist = $.parseJSON(data);

vl5x的值是是用getKey()函数算出来的,但getKey不在这个js文件里,继续找,终于,在网页的初次请求响应中找到了这段

    var _fxxx = function (p, a, c, k, e, d) { e = function (c) { return (c < a ? "" : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36)) }; if (!''.replace(/^/, String)) { while (c--) d[e(c)] = k[c] || e(c); k = [function (e) { return d[e] } ]; e = function () { return '\\w+' }; c = 1; }; while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]); return p; }
    eval(_fxxx('0 2=1;0 3=\'4\'', 5, 5, 'var|5|_1|_2|ookie'.split('|'), 0, {}));
    eval(_fxxx('c f(){' + (_1 + 4) + ' i=e-h-8-2;9 7=g(\'d\');9 6=7.0(i,i*' + _1 + ')+7.0((i+1)*(i+1),3);9 a=6.0(i)+6.0(-4);9 b=' + (_1 + 1) + '.0(4)+a.0(-i-1);7=j(6).0(i-1,l);k 7}', 22, 22, ('substr||||||str|c||var|||function|vjkl' + _1 + '|2' + _1 + '|getKey|getC' + _2 + '|10||hex_md5|return|' + (_1 * _1 - 1)).split('|'), 0, {}))

这是什么鬼,google之,貌似这是一种打包(pack)技术,代码开头都是eval,特征字符串是function(p,a,c,k,e,r)或者function(p,a,c,k,e,d),由dean edwards提出的, 其个人主页 ,找个 unpack工具,把上面代码全复制进去unpack必然是得不到结果的,一段一段来吧,首先把第1个eval中的_fxxx用function的定义替换,然后unpack得到如下代码

var _1 = 5;
var _2 = 'ookie'

这个和getKey又有什么关系,仔细观察,第2个eval中经常会出现 _1,_2,用第一次unpack出来的值替换_1,_2

eval(function (p, a, c, k, e, d) { e = function (c) { return (c < a ? "" : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36)) }; if (!''.replace(/^/, String)) { while (c--) d[e(c)] = k[c] || e(c); k = [function (e) { return d[e] } ]; e = function () { return '\\w+' }; c = 1; }; while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]); return p; }('c f(){' + (5 + 4) + ' i=e-h-8-2;9 7=g(\'d\');9 6=7.0(i,i*' + 5 + ')+7.0((i+1)*(i+1),3);9 a=6.0(i)+6.0(-4);9 b=' + (5 + 1) + '.0(4)+a.0(-i-1);7=j(6).0(i-1,l);k 7}', 22, 22, ('substr||||||str|c||var|||function|vjkl' + 5 + '|2' + 5 + '|getKey|getC' + 'ookie' + '|10||hex_md5|return|' + (5 * 5 - 1)).split('|'), 0, {}))

再unpack试一下,果然,getKey()露出了正面目

function getKey() {
    var i = 25 - 10 - 8 - 2;
    var c = getCookie('vjkl5');
    var str = c.substr(i, i * 5) + c.substr((i + 1) * (i + 1), 3);
    var a = str.substr(i) + str.substr( - 4);
    var b = str.substr(4) + a.substr( - i - 1);
    c = hex_md5(str).substr(i - 1, 24);
    return c
}

这里还有个getCookie(‘vjkl5’)需要再剥一下,在网页的初次请求时,服务器会设置响应Cookie
这里写图片描述
getCookie(‘vjkl5’)就是要获取这个Cookie值,其他的函数在md5.js这个文件中都能找到。解决了vl5x值的计算,然后就开始使劲爬吧,这个过程将是漫长的,请耐心等待。
友情提醒:同一IP频繁访问文书网很容易跳到验证码验证页,为了高效爬取所需的内容,找个稳定的代理IP POOL再爬哦。

评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值