声明:知乎加密逆向分析仅用于研究和学习
这篇文章的学习内容是以知乎关键词搜索接口为案例,对JS
逆向的整个过程进行详细分析;
下面会进行以下几步进行分析(下方演示过程全部使用ch爬虫是什么rome
浏览器);
- 锁定关键接口;
- 锁定关键字段;
- 破解关键字段;
- python爬虫结果演示;
一.锁定关爬虫搜索引擎键接口
进入知乎,在首页上方的搜索输入框中输入任意关键词,点击“查询”,锁定查询接口,如下图:
通过上图中的第一步、第二步、第三步查找,我们肯容易锁定对应的查询接口/search_v3
;
二. 锁定关键字段
锁定查询接口后,下面我们查看接口请求时需要的数据:
通过查看请求头,其中有几个字段非常可疑(特别是x-zse-96
、x-zst-81
字段,似乎都是加密后的数据):
x-zse-93: 101_3_2.0
x-zse-96: 2.0_aTO8Uvu0o8FxNBOqZqFB2098c0Nxb变量英语Rty1Xxq6i9ynCSY
x-zst-81: XXXXXXXXX
这里我们很容易锁定关键字段就是:变量是什么意思x-zse-96
;
有同学可能会问了:“我艹,怎么就很容易锁定是x-zse-96
了?同样x-zst-81也是像是一串密文呀?你女配每天都在为国争光是怎么排除x-zst-81
的?”。大家有疑问也很正常,这也是很多社区里其他人分享时这样说的,给他家爬虫软件是干什么的讲的不明爬虫技术抓取网站数据不白,女配美炸天导致学了根没学一样,看了更迷糊了、、、。好了,下面给大家上干货:
高能总结:
- 请求对比:我们搜索不同关键词两次以上,对比请求数据,找不同,
val变量的定义ue
不同的字段及是关键爬虫搜索引擎字段;- 技巧1:开启女配没有求生欲txt宝书网
preserve lo变量名g
(上图中的1.
的位置)保留上次的接口请求; (说明:我们每次进行关键词查询时会发现Network
面板的接口都会被重新刷新,上一次的接口数据都没了,没发跟上次接口做对比,开启后接口和抽象类的区别上次的请求数据就不会被变量之间的关系刷掉了);- 技巧2:接口过滤(上图中的
2.
的位置);(说明:每次请求会有接口测试很多我们不需要的接口,过滤后只剩下s爬虫软件是干什么的earch_v3
,更便于对比,更容易的变量名找到不同点,排除干扰)
锁定了关键字段之后,如果我们破解了该字段,那不就意味这个接口就被我们破解了吗?下面对x-zse女配美炸天-96
字段逆向;
三. 破解关键字段
定位x-zse-96
字段爬虫技术出现的位置;方法:调试面板右上角,点击更多
图标>search
&接口测试gt;输入x-zse-96
&g女配没有求生欲txtt;回车,如下图:
高能总结:
在关键字段调试时,最好开启浏览器的无痕模式(
chrome
浏览器mac
系统快捷键:⇧+⌘+n
),避免浏览器缓存带来的影响。
点击上图中的第难破mg5日剧五步
格式化代码之后,看接口英文到关键字所在位置,如下图,第12509行;
高能总结:
技巧:由于我们此时并不知道这个js文件中该字段出现爬虫是什么多少次,以免调试时出现不进断点,所以我变量值们先查询一下浏览器哪个好,把出现的地方都看一下,无法排除的都打上断点,如下图中,找到两个位置,无法排除哪个没用,所以都打上了断点;
对上图里的标记分析:
可以看到,在js的第12509行出现了x-zse-96
关键字,此行重点是y
,y
的值又来自m.signatur爬虫技术e
,m.signature
的值又来自u()(f()(s))
,到此,如果我们解出了s,f,u
的话,那么我们就能得到x-zse-96
的值;
高能总结:
技巧:断点的位置哪里最合适?
说明:打断点时最接口是什么好是打在函数的首行(上图中第12490行)、r女配满眼都是钱et爬虫技术urn处(上图中第12498行)、结果行(上图接口英文中第1爬虫python入门2509行),其它地方自己按需打点;原因是,如果不在函数首行断点,只打结果行(12509行),上面的变量可能被其它作用域里的数据污染,导致我们数据异常,大家试一试就知道了;
下面开始debug,查找u()(f()(s))
中的s
,s=[r, a, i, V(c) && c, o].filter(Boolean).join("+"女配每天都在抱大腿我要成仙)
,s
的值是根据好多字段组成的数组进行拼接而成,通过debug
可找出每接口测试用例设计个内容的值以及函数的作用:
如上图,很容易得到r,i,o
的值:
-
r
: 每次请求都一样,貌似是个定值; -
i
: 每次请求都一浏览器样,查看cookie女配没有求生欲txts
,发现这个值跟cookies
里的dc0
的值一摸一样,应该就是来自cookies
了; -
o
: 调试发现是null
;
下面来看a, c
的值是怎么来的,a
是G(e)
函数返变量英语回的,如下图:
高能总结:
技巧:有两种方法找到
G
函数的具体位置:1.是浏览器推荐鼠标悬浮在
G
上,出现悬浮框,点击里面提示的XXXX.js
进接口英文入;2.断点
⬇️
箭头进入
进入G
函数之后发现,里面只是把当前get
请求时的参数进行格式化,然后把pathname
和search
进行字符串拼接而已;c
通过z(t)
函数返回,结果是个""
综上得到了数据:
-
r
:"101_3_2.0"
-
i
:cookies.dc0
-
o
:null
-
a
:"/api/v4/search_v3?"+ path.sear女配满眼都是钱ch
-
c
:''
-
V(c)
:''
[r, a, i, V(c) && c, o].filter(Boolean).join("+")
这里就是把上面的[r,a,i]
使用+
拼接成了爬虫技术抓取网站数据字符串而已,因此s
的值就是:
"101_3_2.0+/api/v4/变量值search_v3?t=general&q=121&correction=1&offset=0&limit=20&filter_fields=&lc_idx=0&show_all_topics=0&search_source=Normal+"ABARdK2yAxW变量英语PTq_5HDAIBPahlStL2uhS36M=|1653805418""
得到了s
的值,继续调试u()(f变量类型有哪些()(s))
,如下图
高能总结:
技巧:调试到
u()(f()(s))
这行时,u、f、s
前面都有一个➡️
,这个箭头表示可以分别对这些函数进行断点
此时,我们把f()(s)
用鼠标选中,发现悬浮框里的值变了,也变量与函数就是说s
被加密了(根据特征看,貌似是一个md5
加密的值,这里是猜的,没有猜到也无所谓,继续往下看爬虫python)爬虫技术
单步调试,当断点进入到s
前面时(在12498行需要点击3次单步调试按钮哦),s
前面的肩头会亮起来(如上图),此时点击单步调试按钮⬇️
进入f
函数里,如下图:
上图里的第二步
的位置就是函数f接口类型
的具体变量位置,如变量果有js
逆向经验的话,你可能一眼就能看出来,这个地方很像md5
加密函数(大家可以下载一个md5
文件对比一下写法,看看是不是很像);往上翻一下,看到这里确实变量名的命名规则在运行一个独立的模块,通过模块的规则、关键属性,我们发现它就是md5
加密的代码,所以我们只需要把这个加密块全部扣出来就行了(也可以不扣,可以使用python
里面安装好的md5
工具包,如果不想安装的话,可以直爬虫软件是干什么的接到这里接口文档扣代码,下面演接口示如何扣代码),扣代码是为了编写python
爬虫时使用;
扣代码:
新建一个文件md5.js
,删除多余的代码,如下图:
我们发现这里是个自执行函数,继续改写,删除函数最后的()
,再把第一行的匿名函数添加一个名字,最后结构就变成了下面这样:
function md5(i) {
// 具体的加密代码我就不贴了,太多了,网上都能找到,主要看结构;
XXX
}
高能总结:
扣代码原则:扣代码尽量保证能不改就不改,能少改就少改;
我们看到de爬虫软件bug
里的加密的结果是"360a2f13a202浏览器下载9e74cab51c1b720203c2"
用我们扣出来的js
代码验证一下,如下图:
与上面的结果一摸一样爬虫技术抓取网站数据,说明我们的结果是对的,继续看u()
函数;
进入u
函数后如下图:
经过观察,我们发现对传进来的值进行了两步操作,第一步是常规的女配没有求生欲藤萝为枝转译encodeURIComponent
,转译之后进行encrypt()
操作,有经验的同接口类型学一眼就能看出来,encr浏览器哪个好ypt
函数就是加密函数常用的名字,所以这里我们继续扣代码,这里完接口测试全不用管这里的encrypt
函数是怎么实现的,同md5
的扣取方法一样,把u
对应的具体函数b
所在上下文里的代码都扣出来,仔细发现这块代码最终浏览器下载是把b
给导出去了,所以扣出来的代码结构爬虫软件如下:
(function() {
"use strict";
function t(e) {
return (t = "function" == typeof Symbol && "symbol" == typeof Symbol.A ? function(e) {
return typeof e
}
: function(e) {
return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e
}
)(e)
}
...
// 具体的加密代码我就不贴了,太多了,网上都能找到,主要看结构;
...
var b = function(e) {
return __g._encrypt(encodeURIComponent(e))
};
// 把b导出去,改写,我们放在window上的sigin_B中
window.sigin_B = b
})()
我们用上面f(浏览器推荐)
函数得到的结果360a2f13a2029e74cab51c1b720203c2
进行加密,对比一下是不是跟de爬虫是什么bug爬虫代码
时的一样,如下图:
不出意外,运变量之间的关系行报错了,因为js变量名的命名规则
运行接口测试时不在浏览器环境里,所有没有window
对象呀,不慌,没有window
,我们直接安装一个js变量值dom
不就行了吗,新建文件夹,使用node
包管理工具npm、yarn
在文件夹里使用npm init
初始化项目,然后安装依赖:
yarn add jsdom
// 或者
npm install jsdom
安装完成之后如下图,在文件最上方引入对应代码,赋值给window
,然后再运行,如下图;
结果又报错了,提示atob不存在,那就使用yarn继续安装atob呗:
yarn add atob
或者
npm install atob
在文件上方引入
const atob = require('atob');
再运行一下试试:
没报错,和debug
的结果对比一下看看:
一抹一样呀,终于出来了,开心!开心!
四.pytho接口类型n爬虫结果
有了上面的分析,python
爬虫的编写就非常简单了,由于时间关系,我就男配每天都在体内成绩不贴代码了,给大家看一下结果吧,如变量泵下图:
终结:
- 整体NPM来说知乎搜索接口的逆向不算复杂;
- 这篇文章过程可能写的过于详细了,对有经验的同学可能显的爬虫有些啰嗦,主要是想照顾一下刚入门的同变量之间的关系学哈;
- 感兴趣的话可以研究一下
x-zst-81
字段看看这个字段是干啥的,尝试解一下,如果需要我这边继续写文章的话,大家可以在文章下面留言,如果大家需要的话,我这边抽时变量类型有哪些间再写一篇关于x-zst-81
的;
后期会持续分享爬虫案例-100例,有兴趣的同学可加入我的知识星球,有更多技巧、高能总结等你哦!!!;