大家好啊,我是小帅
初来乍到就不多说废话了,直接上干货感兴趣的建议你们收藏起来,这样之后方便能找到
1.爬取目标
某乎
2.工具准备
开发工具:pycharm
开发环境:python3.7, Windows10,node.js
使用工具包:requests,md5, execjs
3.项目思路解析
首先搜索我们需要的关键字,获取(疫情相关的文章)
我们能看到这个数据为动态数据信息,动态数据可以通过刷新的方式来观察,加载的速度快一些就是静态数据,慢一些就是动态数据(当然这种的比较适合肉眼观察,实际可以通过查看源代码的方式来判断),抓包在浏览器鼠标右击点击检查,或者按键盘上的f12都能打开抓包工具,怎么去理解这个抓包呢,我画个图给大家理解(他就像是一个中介)
通过抓包的方式获取到我们想要的数据,我们在抓包的数据会比较的杂乱,那我们应该怎样去定位到呢,英语比较好的可以通过他的名字来定位到,刚接触逆向的可以一个个的查看进行定位
找到我们所需要的数据,定位到我们发生请求需要的网址,通过requests的库发生请求,发送请求时需要注意我们爬虫核心所做的是模仿客户端发送网络请求,我们需要携带请求头发送网络请求,x-zse-96为加密数据,需要对其进行解析,x-zse-93是固定数据
我们现在需要做的事情就是对x-zse-96进行解密获取到它加密的位置,一般我们所加密是在js进行处理的,也就是我们俗称的js逆向,现在需要去定位到数据加密的位置,我们可以通过XHR断点定位,也可以通过关键字进行定位
点击进入到对应js文件,在搜索定位到详细的断点位置,打上断点,在刷新页面,要是断点正确一定会进入到断点位置,
可以看出x-zse-96是由"2.0_" + y生成的,那我们就需要去解析y的数据值,y的数据值我们可以往上面看 y = O.signature,O是一个函数,调用了o的返回值
signature的数据为u()(f()(s)),那我们只需要解析这个函数 得到返回值就好了
s的数据是:
"101_3_2.0+/api/v4/search/suggest?q=%E7%96%AB%E6%83%85+"AKBdNvE8mhSPTmaPcLOssLsHp5gV4HXnPME=|1646728124"+3_2.0aR_sn77yn6O92wOB8hPZnQr0EMYxc4f18wNBUgpTe7tue_tyK6P0E09y-LS9-hp1DufI-we8gGHPgJO1xuPZ0GxCTJHR7820XM20cLRGDJXfgGCBxupMuD_Ie8FL7AtqM6O1VDQyQ6nxrRPCHukMoCXBEgOsiRP0XL2ZUBXmDDV9qhnyTXFMnXcTF_ntRueThHpOIrXqBgFYY9N_bgXq9DV10qpxnDH_DBL0nbNq6gwOhU2CYHCMEguOQUYPv4xO3JeYr_HGPup9xBL1YXc_QUoGeTSBQU2qiwO9PbuqZqL8ah28dcLq-qgmQHpYOU3CTbLGNCOZhwtszqOO17XmT9NqxhYm9CLBKcHLkRxGIJx1HGV0vqfzwg9YtGwmWJNf1rx9cHoVYgx89vCCGeX1WBS_fcX1Sen0YgX1VhULXBc8bBoMDqOBcQ3O0qwVqU2m4Cg_obu0_gYxzU3Y8LeCe4gGzUVshgxm-hHC-rNC"
是我们的网址后面加一个固定的数据值(有时效性)用这一串数据进行加密,首先是通过f这个函数进行加密,得出的数据是这个样子的
如果我们一个一个js代码去扣其实会很麻烦,这个时候可以考虑去对照一些加密的网址套用加密的方式如果能套对能帮助我们节省很多的时间,得出f的函数加密的方式是md5
那我们现在就需要解决就是u()这个函数
这个就是我们的u函数加密的位置,那这个时候很多人就犯难了,这么多js代码我扣到什么时候去了,我们可以使用补环境的方式进行解析,直接把js代码搬过去,
const jsdom = require("jsdom");
const {
JSDOM } = jsdom;
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
window = dom.window;
document = window.document;
XMLHttpRequest = window.XMLHttpRequest;
var exports = {
}
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)
}
Object.defineProperty(exports, "__esModule", {
value: !0
});
var A = "2.0"
, __g = {
};
function s() {
}
function i(e) {
this.t = (2048 & e) >> 11,
this.s = (1536 & e) >> 9,
this.i = 511 & e,
this.h = 511 & e
}
function h(e) {
this.s = (3072 & e) >> 10,
this.h = 1023 & e
}
function a(e) {
this.a = (3072 & e) >> 10,
this.c = (768 & e) >> 8,
this.n = (192 & e) >> 6,
this.t = 63 & e
}
function c(e) {
this.s = e >> 10 & 3,
this.i = 1023 & e
}
function n() {
}
function e(e) {
this.a = (3072 & e) >> 10,
this.c = (768 & e) >> 8,
this.n = (192 & e) >> 6,
this.t = 63 & e
}
function o(e) {
this.h = (4095 & e) >> 2,
this.t = 3 & e
}
function r(e) {
this.s = e >> 10 & 3,
this.i = e >> 2 & 255,
this.t = 3 & e
}
s.prototype.e = function(e) {
e.o = !1
}
,
i.prototype.e = function(e) {
switch (this.t) {
case 0:
e.r[this.s] = this.i;
break;
case 1:
e.r[this.s] = e.k[this.h]
}
}
,
h.prototype.e = function(e) {
e.k[this.h] = e.r[this.s]
}
,
a.prototype.e = function(e) {
switch (this.t) {
case 0:
e.r[this.a] = e.r[this.c