大家好,我是不温卜火,是一名计算机学院大数据专业大三的学生,昵称来源于成语—​​不温不火​​​,本意是​​希望自己性情温和​​​。作为一名互联网行业的小白,博主写博客一方面是为了记录自己的学习过程,另一方面是总结自己所犯的错误希望能够帮助到很多和自己一样处于起步阶段的萌新。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!
爬虫入门经典(二十) | 破解JS加密之有道翻译_时间戳



​PS:由于现在越来越多的人未经本人同意直接爬取博主本人文章,博主在此特别声明:未经本人允许,禁止转载!!!​



目录



爬虫入门经典(二十) | 破解JS加密之有道翻译_ide_02


推荐

爬虫入门经典(二十) | 破解JS加密之有道翻译_时间戳_03

  ♥各位如果想要交流的话,可以加下QQ交流群:974178910,里面有各种你想要的学习资料。♥

  ♥欢迎大家关注公众号【不温卜火】,关注公众号即可以提前阅读又可以获取各种干货哦,同时公众号每满1024及1024倍数则会抽奖赠送机械键盘一份+IT书籍1份哟~♥

爬虫入门经典(二十) | 破解JS加密之有道翻译_ide_04

一、小小课堂

爬虫入门经典(二十) | 破解JS加密之有道翻译_ide_05

本文是应粉丝要求写的,本来可能要等到我有空闲时间再写,但是由于博主最近看了关于JS破解的相关知识。就想着先找个实战demo进行测试,这就是此篇博文产出的大题过程。

之前博主做了通过百度翻译的接口制作一个简易的翻译软件。当时由于没有想太多,只是对其汉译英与英译汉进行了简单的测试就发了出来。后来经过粉丝的测试,告知了我此程序在翻译句子的时候会报错。如下图:

爬虫入门经典(二十) | 破解JS加密之有道翻译_ide_06

博主在破解了有道翻译之后,再次测试,发现翻译句子可以完美运行,如下图:

爬虫入门经典(二十) | 破解JS加密之有道翻译_json_07

嗯!这也算是间接的增加了翻译的功能了哈哈!

二、加密与解密

我们在爬取数据时,有的数据是通过加密解密得到的。这时,有人会问道什么是加密?那么又是如何解密的呢?

加密与解密,通俗的来讲就是:


  • 加密:把明文变成密文
  • 解密:把密文变成明文

市面上常见的加密方式有三种:


  • 1、js加密
  • 2、css加密
  • 3、base64加密

爬虫入门经典(二十) | 破解JS加密之有道翻译_爬虫_08

本篇博文讲解的是​​js加密的破解​​!

本次选用的案例为有道翻译:​​http://fanyi.youdao.com/​​​

爬虫入门经典(二十) | 破解JS加密之有道翻译_ide_09

下面咱们要做的就是模拟有道翻译进行单词的翻译。

三、分析

爬虫入门经典(二十) | 破解JS加密之有道翻译_时间戳_10

3.1 分析尝试(初次)


  • 1.翻译一句话
    爬虫入门经典(二十) | 破解JS加密之有道翻译_时间戳_11
  • 2. 查看URL

这个时候我们就可以拿到我们请求的URL

爬虫入门经典(二十) | 破解JS加密之有道翻译_时间戳_12

URL为:

http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
  • 3. 查找参数
    爬虫入门经典(二十) | 破解JS加密之有道翻译_时间戳_13
    先把此部分复制出来
"""
i: 你好
from: AUTO
to: AUTO
smartresult: dict
client: fanyideskweb
salt: 16032741765278
sign: b25367e1be33d7529a099d200c8f7dd3
lts: 1603274176527
bv: 4abf2733c66fbf953861095a23a839a8
doctype: json
version: 2.1
keyfrom: fanyi.web
action: FY_BY_CLICKBUTTION
"""

我们将其转换成字典(dict),代码如下

from pprint import pprint

data = """i: 你好
from: AUTO
to: AUTO
smartresult: dict
client: fanyideskweb
salt: 16032741765278
sign: b25367e1be33d7529a099d200c8f7dd3
lts: 1603274176527
bv: 4abf2733c66fbf953861095a23a839a8
doctype: json
version: 2.1
keyfrom: fanyi.web
action: FY_BY_CLICKBUTTION"""

pprint({i.split(": ")[0]:i.split(": ")[1] for i in data.splitlines()})

爬虫入门经典(二十) | 破解JS加密之有道翻译_python_14

把此部分复制出来如下:

{'action': 'FY_BY_CLICKBUTTION',
'bv': '4abf2733c66fbf953861095a23a839a8',
'client': 'fanyideskweb',
'doctype': 'json',
'from': 'AUTO',
'i': '你好',
'keyfrom': 'fanyi.web',
'lts': '1603274176527',
'salt': '16032741765278',
'sign': 'b25367e1be33d7529a099d200c8f7dd3',
'smartresult': 'dict',
'to': 'AUTO',
'version': '2.1'}
  • 4. 添加请求头

我们先来看下,有道翻页此网页的请求头

爬虫入门经典(二十) | 破解JS加密之有道翻译_python_15

我们可以看到有多种请求,其实一般我们爬取网页内容,并不需要全部添加,除非需要。一般我们添加​​User-Agent​​即可。

在此,博主由于已经提前测试过了。因此就给出所需要的请求头部分

headers = {
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36',
'Origin': 'http://fanyi.youdao.com',
'Referer': 'http://fanyi.youdao.com/',
'Cookie': 'OUTFOX_SEARCH_USER_ID=-1808168645@10.108.160.208; JSESSIONID=aaaRyVJv8oEwg7dPaWrux; OUTFOX_SEARCH_USER_ID_NCOO=704285648.1294403; ___rl__test__cookies=1602406917270'
}
  • 5. 测试代码

????,到这我们就可以进行初步测试了。代码如下:

import requests

url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
headers = {
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36',
'Origin': 'http://fanyi.youdao.com',
'Referer': 'http://fanyi.youdao.com/',
'Cookie': 'OUTFOX_SEARCH_USER_ID_NCOO=1393050056.867326; OUTFOX_SEARCH_USER_ID="1960068844@10.108.160.18"; _ga=GA1.2.1058335445.1601859339; P_INFO=18240707138|1602644960|1|youdaonote|00&99|null&null&null#hen&410100#10#0|&0|null|18240707138; _gid=GA1.2.1420409534.1603269583; JSESSIONID=aaaimJ33Iywd1fQBRukvx; ___rl__test__cookies=1603274176525'
}
data = {'action': 'FY_BY_CLICKBUTTION',
'bv': '9caf244986fe6d1de38207408302e500',
'client': 'fanyideskweb',
'doctype': 'json',
'from': 'AUTO',
'i': '你好',
'keyfrom': 'fanyi.web',
'lts': '1603274176527',
'salt': '16032741765278',
'sign': 'b25367e1be33d7529a099d200c8f7dd3',
'smartresult': 'dict',
'to': 'AUTO',
'version': '2.1'
}
response = requests.post(url=url,headers=headers,data=data)
print(response.content.decode("utf-8"))

爬虫入门经典(二十) | 破解JS加密之有道翻译_python_16

我们这时发现,当修改翻译内容的时候,得不到想要的结果。其实做为一个合格的爬虫开发者,应该有敏感性。

二、JS破解

爬虫入门经典(二十) | 破解JS加密之有道翻译_ide_17

我们此时可以重新看一下所获取的参数:

爬虫入门经典(二十) | 破解JS加密之有道翻译_时间戳_18

2.1 验证时间戳

此时我们可以进行验证。

百度搜索时间戳在线转换工具即可。链接:​​https://tool.lu/timestamp/​


  • 1. lts
    爬虫入门经典(二十) | 破解JS加密之有道翻译_爬虫_19
  • 2. salt

我们先来对比下lts和salt

'lts': '1603274176527',
'salt': '16032741765278',

通过对比我们发现,只是多了最后一个数字,那么salt到底是什么呢?我们现在并不知道,不过我们可以通过查找确定其位置,然后判定其到底是什么。

2.2 JS的破解方式

1. 普通JS的破解方式

爬虫入门经典(二十) | 破解JS加密之有道翻译_爬虫_20

这种方法不经常使用, 因为一旦出现多个相同的JS就很麻烦,

2. 通用JS破解方式


  • 1. 先通过Srearch查找translate_o
    爬虫入门经典(二十) | 破解JS加密之有道翻译_json_21
  • 2. 格式化JS 然后继续搜索translate_o
    爬虫入门经典(二十) | 破解JS加密之有道翻译_python_22
  • 3. 查找salt:
    爬虫入门经典(二十) | 破解JS加密之有道翻译_python_23
  • 4. 断点调试js,查看变量值,再次确认。

由于之前已经验证过,所以在此直接给出怎样查找

爬虫入门经典(二十) | 破解JS加密之有道翻译_json_24

断点位置,博主已经提前给出

爬虫入门经典(二十) | 破解JS加密之有道翻译_json_25

在此,我们先把此部分copy出来

var r = function(e) {
var t = n.md5(navigator.appVersion)
, r = "" + (new Date).getTime()
, i = r + parseInt(10 * Math.random(), 10);
return {
ts: r,
bv: t,
salt: i,
sign: n.md5("fanyideskweb" + e + i + "]BjuETDhU)zqSxf-=B#7m")
}
};

经过分析,确认参数:

ts是当前时间戳

bv是使用md5加密​​navigator.appVersion​​,只要浏览器不变,其实可以是固定的

爬虫入门经典(二十) | 破解JS加密之有道翻译_时间戳_26


​salt是时间戳拼接0-9的随机整数字符串​



​sgin是md5加密的​



​这里的e通过断点调试确认e就是翻译的内容​


3. python模拟MD5加密

  • 1. 模拟its和salt
import time
import random

its = str(round(time.time(),3)).replace(".","")
salt = its+str(random.randint(0,9))

print(its,salt)

爬虫入门经典(二十) | 破解JS加密之有道翻译_json_27

  • 2. MD5加密模拟

MD5算法一般用来加密,不可逆。

此部分内容随机输入,最终都是32位的加密字符串

import hashlib

content = "我不温卜火"
md5 = hashlib.md5()
md5.update(content.encode("utf-8"))
ret = md5.hexdigest()
print(ret,len(ret))

爬虫入门经典(二十) | 破解JS加密之有道翻译_python_28

  • 3. 程序中的对比
sign: n.md5("fanyideskweb" + e + i + "]BjuETDhU)zqSxf-=B#7m")

# 此部分修改为
sign = do_md5("fanyideskweb" + params + salt + "]BjuETDhU)zqSxf-=B#7m")

三、完整代码

爬虫入门经典(二十) | 破解JS加密之有道翻译_爬虫_29

# encoding: utf-8
'''
@author 李华鑫
@create 2020-10-10 17:07
Mycsdn:https://buwenbuhuo.blog.csdn.net/
@contact: 459804692@qq.com
@software: Pycharm
@file: 有道翻译.py
@Version:1.0

'''
import requests
import time
import random
import hashlib
from pprint import pprint


def main():
"""主程序"""
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
headers = {
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36',
'Origin': 'http://fanyi.youdao.com',
'Referer': 'http://fanyi.youdao.com/',
'Cookie': 'OUTFOX_SEARCH_USER_ID=-1808168645@10.108.160.208; JSESSIONID=aaaRyVJv8oEwg7dPaWrux; OUTFOX_SEARCH_USER_ID_NCOO=704285648.1294403; ___rl__test__cookies=1602406917270'
}
while True:
params = input("请输入单词:")
data = get_data(params)
response = requests.post(url=url,headers=headers,params=params,data=data)
print(response.json()["translateResult"][0][0]["tgt"])

def do_md5(content):
"""md5方法"""
md5 = hashlib.md5()
md5.update(content.encode("utf-8"))
return md5.hexdigest()

def get_data(params):
"""获取参数"""
lts = str(round(time.time(), 3)).replace(".", "")
salt = lts + str(random.randint(0, 9))
sign = do_md5("fanyideskweb" + params + salt + "]BjuETDhU)zqSxf-=B#7m")
data = {
'action': 'FY_BY_CLICKBUTTION',
'bv': '9caf244986fe6d1de38207408302e500',
'client': 'fanyideskweb',
'doctype': 'json',
'from': 'AUTO',
'i': params,
'keyfrom': 'fanyi.web',
'lts': lts,
'salt': salt,
'sign': sign,
'smartresult': 'dict',
'to': 'AUTO',
'version': '2.1'
}
return data

if __name__ == '__main__':
main()

四、运行测试

爬虫入门经典(二十) | 破解JS加密之有道翻译_时间戳_30

爬虫入门经典(二十) | 破解JS加密之有道翻译_python_31

美好的日子总是短暂的,虽然还想继续与大家畅谈,但是本篇博文到此已经结束了,如果还嫌不够过瘾,不用担心,我们下篇见!


爬虫入门经典(二十) | 破解JS加密之有道翻译_json_32


  好书不厌读百回,熟读课思子自知。而我想要成为全场最靓的仔,就必须坚持通过学习来获取更多知识,用知识改变命运,用博客见证成长,用行动证明我在努力。  


爬虫入门经典(二十) | 破解JS加密之有道翻译_python_33

爬虫入门经典(二十) | 破解JS加密之有道翻译_ide_34