python代码:
import execjs
import requests
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
token_url = "https://dict.cnki.net/fyzs-front-api/getToken"
url = 'https://dict.cnki.net/fyzs-front-api/translate/literaltranslation'
session = requests.session()
def get_token():
headers = {
'User-Agent': UA,
}
response = session.get(url=token_url,headers=headers).json()
token = response['data']
return token
def get_encrypted_words(words):
js_code = execjs.compile(open('demo.js','r',encoding='utf-8').read())
encrypted_words = js_code.call('s',words)
return encrypted_words
def get_translated_words(token,encrypted_words):
headers = {
'User-Agent': UA,
'Token':token,
}
data = {
'translateType': "0",
'words': encrypted_words,
}
response = session.post(url=url,json=data,headers=headers)
result = response.json()['data']['mResult']
return result
if __name__ == '__main__':
words = input('请输入你要翻译的句子:')
token = get_token()
encrypted_words = get_encrypted_words(words)
translated_words = get_translated_words(token,encrypted_words)
print('翻译结果为:',translated_words)
js代码:
const CryptoJS = require('crypto-js');
n = "4e87183cfd3a45fe"
function s(t) {
var e = {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}
, i = CryptoJS.enc.Utf8.parse(n)
, s = CryptoJS.AES.encrypt(t, i, e)
, r = s.toString().replace(/\//g, "_");
return r = r.replace(/\+/g, "-"),
r
}
结果展示:
首先抓包,发现翻译请求为post请求且有翻译的内容加密。
先请求获取数据,发现请求头不加token是获取不到数据的,获取token要专门去访问一个网址获得,且为了保持请求翻译时登陆状态一致,需要用session发送请求。
如何定位 words的加密位置呢,两种方法,一搜索translateType关键字,在去打断点定位。
二是因为这是xhr请求,因此可以xhr断点请求。释放xhr断点,接着在这里打断点,点击翻译。在右侧可以找到加密的words值
接着往上跟栈,找没有被加密的地方。最后发现在这里
释放其他断点,点击翻译,在这里打上断点
在控制台打开,发现由h.encrypto函数加密,进入它 ,即函数s(t)
释放其他断点,在return处打上断点,点击翻译。
发现a是一个标准AES加密算法,复制代码,复制n,在js中调用专门的库,替换a
注意:获取token的网址我也不知道咋来的,看别人的代码。
写代码遇到的错误:{"timestamp":"2024-04-07T20:03:35.755+0800","status":415,"error":"Unsupported Media Type","message":"Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported","path":"/fyzs-front-api/translate
这个错误表明服务器不支持请求中指定的媒体类型。具体地说,服务器不支持 'application/x-www-form-urlencoded;charset=UTF-8' 这种媒体类型。
要解决这个问题,您可以尝试使用其他媒体类型发送请求,例如 'application/json'。您需要确保将请求的数据转换为 JSON 格式,并使用适当的请求头来指定媒体类型为 JSON。
teraltranslation"}
思考:以后遇到请求头需要token值,去哪里找到token值呢?