js加密反爬虫,爬虫js逆向入门,js逆向解密之网络爬虫

js加密反爬虫,爬虫js逆向入门,js逆向解密之网络爬虫

在这篇内容中,边肖为大家整理了关于js反向解密网络爬虫的相关知识点。请有需要的朋友参考。

1 引言

几个月前写了一个网站的爬虫(请原谅我捂耳朵)这两天需要再次采集,使用scrapy-redis框架。本以为第二次抓取可以轻松完成,没想到爬虫启动后几秒钟,就出现了大量的重试提示,心里顿时咯噔一下。我的闲暇时间估计要结束了。

仔细分析,发现获取店铺列表的请求有问题。通过浏览器抓取数据包,发现请求头参数中多了一个X-Shard和x-uab参数,如下图所示:

X-Shard没毛病。乍一看是兴趣点的经纬度,但是x-uab看过之后,让人觉得很苦涩。js加密了,所以只能反过来解密。

2 js逆向求解

最直接的思路是根据“x-uab”关键字搜索所有的键(在chrome浏览器-source中按ctrl shift F快捷键),结果如下:

接下来制作一个断点进行调试:点击数字,数字位置出现一个蓝点,表示断点添加成功。然后刷新页面以获取商店列表,程序将在断点处停止。如下所示:

在控制台中调试o.getUA()函数,并查看输出:

果然证明猜测是正确的,就是这个o.getUA()函数负责生成请求头中的x-uab参数。

继续往下看这个getUA()函数的引用(把光标放在要查看的函数上可以查看这个函数的引用),就是下面这个函数:

图中的s就是我们想要的x-uab参数,下图可以在控制台输出中得到证明:

于是,u-xab在这里由E生成,函数E传入的参数中,第一个是常数2,第二个参数A是未定义的。呵呵,好像没有传其他参数。继续往下看这个e(2,a)函数:

这是函数e(r,I,n,h,p)方法,可以直接运行获得加密参数。取出这个函数e(r,I,n,h,p)方法的所有代码,保存为js文件。

回到顶端

3 撸代码

3.1方案1

你以为找出生成x-uab的js代码就完事了吗?少年,你太年轻太单纯了!

如何运行这个js脚本是off (nan)键(dian)。

这个函数e(r,I,n,h,p)函数有将近40000行代码。重新实现Python中的难(就)度(时)有(不)点(可)和大(能)。所以我选择直接用Python来执行这个js脚本。

如何在python中执行js脚本?度娘会给你一堆资料。你自己检查一下。我在这里选了execjs。

因为在上面复制的脚本中,只定义了一个e(r,I,n,h,p)方法,并且没有调用这个方法,所以我准备在js文件的末尾添加一些代码来调用:

函数getParam() {

var a;

var param=e(2,a);

返回参数

};

然后,启动Python代码:

导入execjs

node=execjs.get()

file='eleme.js '

ctx=node.compile(打开(文件))。read())

js_encode='getParam()'

params=ctx.eval(js_encode)

打印(参数)

尝试执行,冷心,代码异常:

执行。_ exceptions . program error:type error:“window”未定义。

window对象估计是浏览器打开时创建的,包含了浏览器的信息,所以这段代码在Python中执行时,并没有这样的一对。本来我是想伪造window对象的,但是搜了一下发现js脚本里有上百个地方用到了window。这不是结局。代码混乱,下一关不够,无法溯源(这个地方困扰我很久了。如果哪位学长知道方法,请告诉我)。

后来从一位前辈那里学了一个绕过去的方法(感谢前辈)。这位前辈的方法是把execjs的引擎改成Phantomjs,一个无头浏览器(之前用的引擎是node.js),换句话说就是用Phantomjs来执行JS脚本。PhantomJS是浏览器,自然会创建窗口对象。

在使用PhantomJS之前,需要下载它的驱动,然后在统一目录下放下Python代码。之前的Python代码也进行了修改:

导入execjs

导入操作系统

OS . environ[' exec js _ RUNTIME ']=' phantom js '

node=execjs.get()

file='eleme.js '

ctx=node.compile(打开(文件))。read())

js_encode='getParam()'

params=ctx.eval(js_encode)

打印(参数)

果然,按照这个方法,成功获得了加密字符串。

3.2选项2

其实这个方案2是我在出现未定义窗口对象异常后尝试的第一个方法。但是因为js代码中添加的js脚本出现了问题,我觉得行不通,于是咨询了前辈,得到了方案一。

第二个方案的思路和第一个方案差不多,但更粗暴。不是因为不在浏览器中执行所以没有窗口对象吗?然后我会模拟浏览器来执行它。

在执行之前,还要修改js脚本,调用js文件末尾的E方法,并添加以下代码:

var a;

var param=e(2,a);

返回参数;

记住:不要放在任何函数里。我之前在函数中强制使用了这段代码,结果在浏览器中获得了加密字符串,但在Python中却没有。

selenium和chrome的webDriver进行浏览器模拟,代码如下:

从selenium导入web驱动程序

浏览器=webdriver。chrome(executable _ path=' chrome driver . exe ')

用open('eleme.js ',' r ')作为f:

js=f.read()

打印(browser.execute_script(js))

这个方法也可以得到加密的字符串。

最后有必要说一下,如果需要获取大量的x-uab,采用第二种方案效率会更高,因为如果采用第二种方案,可以打开一个浏览器(都是调用一个webdriver对象)然后快速执行js返回加密字符串。

4 总结

js反向解密完成。但这也留下了一些问题:

(1)使用chrome断点调试时,js脚本被压缩混乱,可以通过chrome的pretty print功能(就是那一对花括号)进行格式化美化,但是有时候会失败,如下图所示。格式化后还是一团乱:

这个问题耽误了我很久,我没法调试!

(2)在js基础下不起作用。我很困惑,为什么在运行时,先通过o.getUA()调用E函数内部的嵌套函数,然后在E函数内部的嵌套函数中调用E方法本身。这是什么操作?不是所有的函数调用都应该从外层函数开始,然后调用嵌套函数吗?

(3)如果浏览器执行js的方法不适用,只能替换window对象。我该怎么办?

(4)这个E函数有将近4万行,一个加密函数有这么多代码。我不相信。这里面肯定有很多令人困惑的东西,但我已经尝试过调试和追踪了。我只能说,迷茫过后,我无法追寻,头晕目眩。我们如何简化这个脚本?

如果有学长能回答你的问题,请告诉我。我会很感激的!谢谢大家!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: