六、JS解析
1.定位js文件
- 1.通过initiator定位到js文件
- 2.通过search搜索关键字定位到js文件
- 3.通过元素绑定的事件监听函数找到js文件,Event Listeners
- 注:三种方法不能保证每一种都能找到js文件,都试试
2.js代码分析,掌握加密步骤
- 可以加断点
3.模拟重现
-
1.通过第三方js加载模块直接加载js运行,js2py pyv8 execjs等
-
js2py模块,是一个js的发翻译工具,也是一个通过纯python实现的js解释器
-
js执行思路
- 1.在了解js内容和执行顺序后,通过python来完成js的执行过程,得到结果
- 2.在了解js内容和执行顺序之后,使用类似js2py的模块来执行js代码,得到结果
- 但是在使用python程序实现js执行的时候,需要观察js的每一个步骤,非常麻烦,所以更多时候我们会选择使用类似js2py的模块去执行js,接下来我们来使用js2py实现人人网登录参数的获取
-
具体实现
import js2py import requests # 创建js执行环境 context = js2py.EvalJs() # 手机端的headers headers = { "User-Agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Mobile Safari/537.36" } # 先把js文件下载下来 big_js = requests.get("http://s.xnimg.cn/a85738/wap/mobile/wechatLive/js/BigInt.js",headers=headers).content.decode() # 然后加载js文件 context.execute(big_js) # 再调用这个函数 context.execute("setMaxDigits(130);")
-
人人网登录
import requests import js2py import json def login(): # 创建session对象 session = requests.session() # 设置请求头 session.headers={ "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Mobile Safari/537.36" } # 发送获取公钥数据包的get请求 获取rkey response = session.get('http://activity.renren.com/livecell/rKey') # print(response.content.decode()) # 创建n n = json.loads(response.content.decode())['data'] # print(n) # 创建t t = { "password":"wangtaotao." } # 获取前置js代码 rsa_js = session.get("http://s.xnimg.cn/a85738/wap/mobile/wechatLive/js/RSA.js").content.decode() bigint_js = session.get("http://s.xnimg.cn/a85738/wap/mobile/wechatLive/js/BigInt.js",).content.decode() barrett_js = session.get("http://s.xnimg.cn/a85738/wap/mobile/wechatLive/js/Barrett.js",).content.decode() # 创建js环境对象 context = js2py.EvalJs() # 将变量和js代码加载到环境对象中执行 context.execute(rsa_js) context.execute(bigint_js) context.execute(barrett_js) context.n = n context.t = t # 将关键js代码放到环境对象中执行 pwd_js= """ t.password = t.password.split("").reverse().join(""), setMaxDigits(130); var o = new RSAKeyPair(n.e,"",n.n) , r = encryptedString(o, t.password); """ context.execute(pwd_js) # 获取加密密码 # print(context.r) # 构建formdata formdata = { "phoneNum": "15041890905", "password": context.r, "c1": -100, "rKey": n["rkey"] } # print(formdata) # 发送post请求,模拟登录 response = session.post('http://activity.renren.com/livecell/ajax/clog',data=formdata) # 验证 print(response.content.decode()) if __name__ == '__main__': login()
-
-
2.纯Python重现
-
模拟有道翻译
''' i: 人生苦短,及时行乐 from: AUTO to: AUTO smartresult: dict client: fanyideskweb salt: r.salt sign: r.sign ts: r.ts bv: 7bf45b9559005ebb942310bf3549b33e doctype: json version: 2.1 keyfrom: fanyi.web action: FY_BY_CLICKBUTTION ''' import requests import hashlib import time import random import json class Youdao(object): # 初始化 def __init__(self,word): self.url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule" self.headers = { "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Mobile Safari/537.36", "Cookie": "OUTFOX_SEARCH_USER_ID=1455553639@10.108.160.19; JSESSIONID=aaac4QudHCU3F6FYn3d_w; OUTFOX_SEARCH_USER_ID_NCOO=1574171141.1067092; ___rl__test__cookies=1578465296973", "Referer":"http://fanyi.youdao.com/", } self.formdata = None self.word = word # 构建不固定的参数 def generate_formdata(self): """ ts: r = "" + (new Date).getTime(), salt: ts + parseInt(10 * Math.random(), 10), sign: n.md5("fanyideskweb" + e + i + "n%A-rKaT5fb[Gy?;N5@Tj") } """ # 模拟时间戳 ts = str(int(time.time() * 1000)) # 模拟0-9随机数 salt = ts + str(random.randint(0,9)) # sign tempstr = "fanyideskweb" + self.word + salt + "n%A-rKaT5fb[Gy?;N5@Tj" md5 = hashlib.md5() md5.update(tempstr.encode()) sign = md5.hexdigest() self.formdata = { "i": self.word, "from": "AUTO", "to": "AUTO", "smartresult": "dict", "client": "fanyideskweb", "salt": salt, "sign": sign, "ts": ts, "bv": "7bf45b9559005ebb942310bf3549b33e", "doctype": "json", "version": "2.1", "keyfrom": "fanyi.web", "action": "FY_BY_CLICKBUTTION", } # 发送post请求 def get_data(self): response = requests.post(self.url,data=self.formdata,headers=self.headers) return response.content.decode() # 解析最后结果 def parse_data(self,data): data = json.loads(data) return data["translateResult"][0][0]['tgt'] # 运行 def run(self): # url # headers # 构建Fromdata self.generate_formdata() # 发送请求,获取响应 data = self.get_data() # 解析数据 response_Data = self.parse_data(data) # 打印翻译结果 print(response_Data) if __name__ == '__main__': youdao = Youdao("人生苦短,及时行乐") youdao.run()
-
-
地址url去重
- url保存集合
- url 转换成hash保存
- 用布隆过滤器
-
文本内容去重
- 编辑距离
- simhash