网页抓取 加密html(2021年最新Python爬虫教程+实战项目案例(上) )

优采云 发布时间: 2022-04-06 17:17

  网页抓取 加密html(2021年最新Python爬虫教程+实战项目案例(上)

)

  今天是综合练习!!它涉及请求、逆向工程、解密和爬取。

  目标是从某音乐软件的评论区抓取热评,可以说是大开眼界了!

  #1.找到未加密的参数 #window.asrsea(参数1,参数2,参数3.。。。。。)

#2.想办法把参数进行加密,(使用的是某云的加密逻辑) #params->encText encSecKey->enSecKey

#3.请求到网页,拿到评论信息

  1.打开网页,输入你想知道的歌曲

  

  2. 进入子页面,抓包,一一查看评论的包在哪里。以下是评论区抓到的包。可以看到评论区的url需要两个参数,params,encSecKey。这两个参数就是加密所涉及的参数,我们只需要破解整个加密逻辑即可

  

  

  3.单击启动器以显示每个 json 文件。最上面的一个是最后处理的文件。我们开始向后推。点击第一个json文件

  

  4.在锚点处设置断点,刷新页面。

  

  5.刷新后,注意scope中的local选项,打开变量查看requests属性,然后点击上面的蓝色按钮,一直释放,直到出现我们想要的评论的url。

  

  6.在调用栈中,在json文件中一一查看我们需要的参数:encText、encSecKey,直到找到参数值,这就是我们的加密参数。我们可以看到它们属于

  var bVj8b是一个变量,这个变量是由函数window.asrsea赋值的,所以我们猜测这个函数是window.asrsea加密的,我们搜索这个函数

  

  7.调用的时候除了这个函数,前面也定义了这个函数。此功能由 d 功能指定。让我们解释一下 d 函数。这里我把 a,b,c,d ,e 这五个函数抄下来,我们一一解读。老实说,我忘记了f,e,g在这里是如何定值的。我只记得d是数据数据,i是随机数,从而确定encSecKey。对应的encText就是我们想要的params。如果您想了解更多,请观看此视频

  2021最新Python爬虫教程+实战项目案例(最新录制)_bilibili _bilibili

  !function() {

function a(a) {#由i值来的

var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";

for (d = 0; a > d; d += 1)

e = Math.random() * b.length,#产生e的随机数

e = Math.floor(e),#对e向下取整

c += b.charAt(e);#e作为b的索引,从b中拿出一个索引为e的字符,附到c上

return c#返回c,这就是a函数的功能,产生一个随机秘钥

}

function b(a, b) {#b函数时加密过程,为AES加密,a是加密内容,b是加密秘钥

var c = CryptoJS.enc.Utf8.parse(b)

, d = CryptoJS.enc.Utf8.parse("0102030405060708")

, e = CryptoJS.enc.Utf8.parse(a)#把a的utf-8格式赋值给e

, f = CryptoJS.AES.encrypt(e, c, {#AES加密,把e和c加密

iv: d,#iv为AES加密的偏移量

mode: CryptoJS.mode.CBC#AES的加密模式

});

return f.toString()#返回f的字符串形式

}

function c(a, b, c) {

var d, e;

return setMaxDigits(131),

d = new RSAKeyPair(b,"",c),

e = encryptedString(d, a)

}

function d(d, e, f, g) {#由window.asrsea来的

var h = {}#创建空字典

, i = a(16);#i值由a函数确定,i值为16位的随机秘钥

return h.encText = b(d, g),#b函数的返回值写进h的encText内,d是待加密数据

h.encText = b(h.encText, i),#可以看出这是两次加密过程,生成encText

h.encSecKey = c(i, e, f),

#encSecKey这个参数就是我们想要的两个参数之一,由c函数确定

#这里c函数需要传进去的参数有i e f ,其中e f 是定值,i是随机值,我们把i值固定就能获得固定的encSecKey值

#至此encSecKey和encText的加密过程全部确定完毕。

h

}

function e(a, b, d, e) {

var f = {};

return f.encText = c(a + e, b, d),

f

}

window.asrsea = d,

window.ecnonasr = e

}();

  

  剩下的就是全部代码了。如果还有时间,我会回来理清逻辑的。我对这篇文章不是很满意。

  #1.找到未加密的参数 #window.asrsea(参数1,参数2,参数3.。。。。。)

#2.想办法把参数进行加密,(使用的是网易云的加密逻辑) #params->encText encSecKey->enSecKey

#3.请求到网页,拿到评论信息

import requests

from Crypto.Cipher import AES

from base64 import b64encode

import json #json 可以把字典变成字符串

url="https://music.163.com/weapi/comment/resource/comments/get?csrf_token="

#请求方式post

data={

"csrf_token": "",

"cursor": "-1",

"offset": "0",

"orderType": "1",

"pageNo": "1",

"pageSize": "20",

"rid": "R_SO_4_40257799",

"threadId": "R_SO_4_40257799"

}

#处理加密过程

""""

function a(a) {#返回随机的16位字符串

var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";

for (d = 0; a > d; d += 1)#循环函数

e = Math.random() * b.length,#生成随机数

e = Math.floor(e),#取整

c += b.charAt(e);#取字符串中的xxx位

return c

}

function b(a, b) {#a是要加密的内容,b是秘钥

var c = CryptoJS.enc.Utf8.parse(b)#c是utf-8的b

, d = CryptoJS.enc.Utf8.parse("0102030405060708")#d是数字的utf-8类型

, e = CryptoJS.enc.Utf8.parse(a)#e是a的utf-8形式

, f = CryptoJS.AES.encrypt(e, c, {#AES加密算法,

iv: d,#AES算法里面的偏移量

mode: CryptoJS.mode.CBC#模式:CBC,差一个秘钥,秘钥就是c,c又是b,所以b的作用就是秘钥

});

return f.toString()

}

function c(a, b, c) {#c算法不产生随机数

var d, e;

return setMaxDigits(131),

d = new RSAKeyPair(b,"",c),

e = encryptedString(d, a)

}

function d(d, e, f, g) {d:d就是数据,e:01001,f:'很长',g:'0CoJUm6Qyw8W8jud'}

var h = {}#声明空对象

, i = a(16);#i是16位的随机字符串

return h.encText = b(d, g),#所以d是数据,g是秘钥

h.encText = b(h.encText, i),#这里得到的encText就是我们要的params,i是秘钥

#从上面两行代码看出,想要得到encText,首先需要两次b加密过程,第一次数据+g,第二次把第一次返回的结果+i

h.encSecKey = c(i, e, f),#这里得到的encSeckey就是我们要的encSeckey,e,f都是固定值,i是随机值

#这里encSeckey的随机值产生都是由于i的原因,我们把i值固定就能获得固定的encSeckey值.

h

}

function e(a, b, d, e) {

var f = {};

return f.encText = c(a + e, b, d),

f

}

"""

f="00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"

i="5wWcgz0OQm8BE9yI"#随机值

e="010001"

g="0CoJUm6Qyw8W8jud"

def get_encSeckey():#由i确定

return "c5c0039e144f4dad02c2fc54dd0a6dcf74c0981748c1c00acba22d79569963ce4434a0f9663a1a048bcc4afbf4d4a389477323ef79b13673439ebb5d1d9895f6ea06c0fcc612e8e475dafca50bed9f51a3a07407be7739f86bd790ff10936947a6f022ec38db5c069968c559f17a617f8546a37dc3b900a469f9c19e0f85873a"

# 把参数进行加密

def get_params(data): # 默认这里接收到的是字符串

first = enc_params(data, g)

second = enc_params(first, i)

return second # 返回的就是params

# 转化成16的倍数, 为下方的加密算法服务

def to_16(data):

pad = 16 - len(data) % 16

data += chr(pad) * pad

return data

# 加密过程

def enc_params(data, key):

iv = "0102030405060708"

data = to_16(data)

aes = AES.new(key=key.encode("utf-8"), IV=iv.encode('utf-8'), mode=AES.MODE_CBC) # 创建加密器

bs = aes.encrypt(data.encode("utf-8")) # 加密, 加密的内容的长度必须是16的倍数

return str(b64encode(bs), "utf-8") # 转化成字符串返回,

resp=requests.post(url,data={

"params":get_params(json.dumps(data)),

"encSecKey":get_encSeckey()#Key写成了key,结果一直出不来!!!!!!!!!!!!!!!

})

print(resp.text)

  最终效果如图

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线