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_wordsdef 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 resultif __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值呢?