手机版

js反向解密的网络爬虫

时间:2021-08-23 来源:互联网 编辑:宝哥软件园 浏览:

1导言

几个月前,我在一个网站上写了关于爬虫的文章(请原谅我偷了铃铛)。这两天我需要再次收集它,使用scrapy-redis框架。我以为第二次爬行可以轻松完成,但是爬虫启动后仅仅几秒钟,就出现了很多重试提示,我的心突然咯噔了一下,我的闲暇时间估计就结束了。经过仔细分析,发现获取店铺列表的请求存在问题。通过浏览器捕获包,发现请求头参数中比以前多了一个X-Shard和x-uab参数,如下图所示:

X-Shard没有错,乍一看是兴趣点的经纬度,但看了让人觉得苦。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方案一

当你找到生成x-uab的js代码时,你认为你完成了吗?少年们,你们太年轻太单纯了!如何运行这个js脚本是nan的关键。函数e(r,I,n,h,p)有近4万行代码,难度(shi)、点(bu)、点(ke)和大(能)在Python中再次实现。因此,我选择使用Python直接执行这个js脚本。如何用python执行js脚本,杜娘会给你一堆资料,自己查一下。我在这里选择了execjs。因为在上面复制的脚本中,只定义了一个e(r,I,n,h,p)方法,并且没有调用这个方法,所以我想在js文件的末尾添加一些代码来调用:

函数GetParam(){ var a;var param=e(2,a);return param };然后,启动Python代码:

Import exec js node=execjs.get()文件=' elemene.js' CTX=node.compile(打开(文件)。read())js _ encode=' getparam()' params=CTX . eval(js _ encode)print(params)尝试执行,但是很酷。

Execjs。_例外。程序错误: type error :“window”没有定义window对象。估计是浏览器打开创建的,里面包含了浏览器的信息。所以用Python执行这段代码的时候,并没有西乡这个东西。本来想伪造window对象,但是搜索后发现js脚本中有几百个地方用了window,还没完成。代码混乱,下一级不够溯源(这个地方困扰我很久了,有没有前辈知道方法请告诉我)。后来我跟一个长辈(感谢长辈)学了一个走动的方法。这个前身的方法是用无头浏览器Phantomjs替换execjs的引擎(之前的引擎是node.js)。换句话说,PhantomJS用于执行JS脚本。PhantomJS是一个浏览器,自然会创建窗口对象。

在使用PhantomJS之前,您需要下载它的驱动程序,然后将其放在统一的Python代码目录中。对之前的Python代码进行更改:

import exec js import osos . environ[' exec js _ RUNTIME ']=' Phantomjs ' node=exec js . get()file=' eleme . js ' CTX=node.compile(打开(文件)。read())JS _ encode=' getparam()' params=CTX . eval(JS _ encode)print(params)果然,按照这个方法,成功获得了加密字符串。

3.2方案二

事实上,方案2是我在未定义窗口对象异常后尝试的第一个方法。但是,因为添加到js代码中的js脚本有问题,所以我认为它不起作用,所以我咨询了我的前辈,得到了方案1。

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

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

风险值a;var param=e(2,a);返回参数;请记住:不要把它放在任何函数中,因为我把这段代码放在一个函数中强制执行,结果是加密的字符串可以在浏览器中获得,但在Python中是None。

模拟浏览器中使用的selenium和chrome的webDriver,代码如下:

selenium import web driver browser=web driver . chrome(可执行文件_路径=' chromedriver.exe ')中的方法,其open ('elemene.js ',' r ')为f : js=f . read()print(browser . exe _ script(js))也可以加密

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

4总结

js反向解密完成。但是仍然存在一些问题:

(1)使用chrome断点调试时,js脚本都是压缩混淆的,可以通过chrome的蛮打印功能(也就是花括号)来美化,但有时候也会失败,就像下图,格式化后还是一塌糊涂:

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

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

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

(4)这个E函数有将近4万行,一个加密函数有这么多代码。我不相信。里面肯定有很多东西让人摸不着头脑,但是我试着去调试和跟踪它。只能说迷茫之后就追踪不到了,头晕。我们如何简化这个脚本?

如果有哪位前辈能解决问题,请告诉我们,我很感激!拜谢!

版权声明:js反向解密的网络爬虫是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。