百度翻译 edu.baidu.com 考频分布 分析sign算法并获取及爬虫

在百度查询单词时,发现百度可以显示这个单词在近些年考了多少次,例如

喜欢瞎鼓捣的我就想着自己用python来实现直接获取考频分布,这样在背一些单词时也能着重记忆。想着先上网找一找,嘿,网上居然没有人这么干过还,只找到有人在解决sign算法,这个后面再说,所以只能自己尝试。

老规矩,打开F12,不难发现是这项在请求

看载荷可以发现是通过网址向后端发送数据,数据分别是“word”、“tag”、“sign”和“callback”,

word和tag一眼就能看出是什么内容,重点实在“sign”和“callback”,熟悉时间戳的话也不难发现callback的内容部分其实是时间戳,和当前时间戳对比的话就会发现猜想是没错的,是时间戳整数加小数点后三位,那么“_”之后的内容又是什么?sign的内容又是什么?

首先继续看callback部分,通过全局搜索jsonp_,发现

在js文件中找到这一部分

通过结构来看,我们找对了,就是这一段生成了callback,这段代码保存下来

再来看sign,这个是最难的部分,通过相似的方法可以找到他在js中是这样的

这个破解就带着很大的运气成分了,首先是我到观察sign的表达式最大为f,且刷新不会改变sign值,其他单词的sign同样如此,并且还都是32位的,第一反应是16位进制,尝试转换为二进制后,发现并无规律,也尝试使用了含有两个相同字母以上的单词进行测试,也没有发现规律。又想到了md5加密,将单词加密后仍然与sign值不相同。“干瞪眼”方法行不通,再返回到我们前面找到的js代码部分,这里我在网上找了很久,但是只找到了反向破解百度翻译sign值的方法,网上其他文中介绍破解sign时也涉及到了js某个函数,但是与这里的完全不同,百度翻译生成sign时会将单词传入函数,再生成sign,但是考频分布这里的sign中d()函数并没有传入任何的数据,在这里卡了很久很久,最终决定尝试通过后半部分来进行入手,还是先观察,this.examTags.wordProto,这个变量从名字来看的意思应该是当前这个tag(即考研还是六级还是四级等)下的单词是什么,再在后面加上“_321188626”,但是与我们前面所获得的32位字符串仍然不同,此时就靠运气,我尝试生成end_321188626的md5加密值,结果和前文的32字符串完全相同!

至此,四个数据及生成方法全部拿到,废话不多说,直接上python代码

import requests
import js2py
import hashlib
import json
import os

def chaxun(word):
    #word = str(input())
    #word='reliance'
    import time
    js='Math.ceil(1e5 * Math.random())'
    r = js2py.eval_js(js)
    time=str(time.time())
    callback='jsonp_' + time[0:10] + time[11:-4] + '_' +str(r)
    tag = '考研'
    sign = word + '_321188626'
    sign = hashlib.md5(sign.encode(encoding='utf-8'))
    sign = sign.hexdigest()
    url = 'https://edu.baidu.com/fanyi/examtags?word=' + word +'&tag=考研&sign='+sign +'&callback=' + callback
    res = requests.get(url).text
    #res= 'jsonp_1679493198005_43684({"code":0,"data":{"tag":"六级","kernel_level":"","word_level":"","recent_years":"5","recent_years_zh":"五","appear_count":"5","importance":"1","definition":[{"text":"v/n. 费心做; 努力 ","partname":"v/n.","percentage":"60%"},{"text":"v/n. 打扰; 使烦心; 麻烦","partname":"v/n.","percentage":"40%"}]}})'
    #print(res.text['recent_years_zh'])
    #print(res)
    try:
        json1 = json.loads(res[26:-1])
    except json.decoder.JSONDecodeError:
        json1 = json.loads(res[25:-1])
    #print(json1)
    try:
        if str(json1['msg'])== '数据不存在':
            print('输入的单词可能有误或考研未涉及')
    except KeyError:
        print('近'+json1['data']['recent_years_zh']+'年出现'+json1['data']['appear_count'] + '次')
        print('重要性:'+str(int(json1['data']['importance'])*'☆'))
        i=0
        for data in json1['data']['definition']:
            print(str(json1['data']['definition'][i]['text']) + '  ' +str(json1['data']['definition'][i]['percentage']))
            i=i+1
        print('\n')

def main():
    print('如果要停止,请输入 endend')
    while True:
        print('输入要查询的单词:')
        word=input()
        print()
        if word =='endend':
            break
        else:
            chaxun(word)


main()
os.system("pause")
Python

运行后提示

如果要停止,请输入 endend
输入要查询的单词:
Python

输入end

近六年出现17次
重要性:☆☆☆
n. 结尾; 最后部分   26%
n/v. 结束; 了结   26%
vphr. (make ends meet)收支相抵   21%
vphr. (end up)最终成为   15%
n. 目的  12%


输入要查询的单词:
Python

我也已经把代码打包好了,如果不想再安装库或者调试,可以用这个获取考频.zip

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
隐藏
变装