一、解决方法:
第一难关: sign标签获取
- 首先介绍一个模块神器 execjs
用途:通过python代码去执行JavaScript代码的库 - 获取sign值
1.按F12打开开发者模式,看它的页面展示结果一看就是个ajax,直接去xhr里找,找到了包数据直接看response响应的结果,发现dst是我们要翻译的结果。【返回的数据太多不好分析按一键,然后再点击翻译按钮】
- 我再去看headers,看到是post请求,一定有表单数据,from to【学过一点英文的应该都知道从…到…】,qurry【翻译的内容】,sign【通过js拿到的】,token【这个参数经过分析,不影响请求,但一定要有】,经过post请求测试需要拿到sign标签
-好的,我们去all里找找看,看看有多少js,鼠标放到Initiator发现就只有两个js文件,好的返回编译器里【我这里用的pycharm】新建俩个js文件,两个js文件全局搜索sign按【citl+f】,发现找到的东西和formdata的几乎类似
发现sign对应这【h(n)】,n由qurry。
- 上面我们找到了sign对应着【h(n)】,好的回到浏览器中,全局搜索那两个js文件查找h(n),加上断点进行debug调试去找h(n),随便输入一个内容,找到了一个【h:f e(r)】f是function,好的在次回到编译器里的js文件中全局搜索【function e®】,找到了一个内容,好的在次新建一个js文件,把内容丢进去
- 接下导入excejs库
import execjs
with open('baidu.js','r') as f:
jsData=f.read()
sign=execjs.compile(jsData).call('e','你好') #e是js传的参数,下一个参数就是翻译的内容
print(sign)
运行了一下发现缺少i 参数,好的再去找i,发现不管翻译什么【i】参数都是固定的,直接加入那个js文件里继续跑
var i="320305.131321201"
发现了又缺少【n】好的再去浏览器里找n的内容,发现n对应着一个函数方法,好的再去那个js里全局搜索那个函数内容,找到那个内容以后直接丢到里的那个js文件中继续跑,看看能不能获取sign的值。
结果发现成功获取到了sign的值,接下来就可以开开心心的写自己的翻译脚本呢
第二难关 发现不管翻译中文英文都是一样的
结果发现是请求方式的问题,from 。。。to。。。。
请求之前需要一个中英文判断,判断方法如下:
def is_chinese(uchar):
"""判断一个unicode是否是汉字"""
if uchar >= u'\u4e00' and uchar<=u'\u9fa5':
return True
else:
return False
二、代码截图
# -*- coding: utf-8 -*-
# @Time : 2021/1/18 14:24
# @Author : Xchen
# @Email : 1272012812@qq.com
# @File : TranslateBaidu.py
# @Software: PyCharm
# token: ea5ada4109c67257a32b444d7add8f51
import requests
import json
import execjs
headers={
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
'cookie': '__yjs_duid=1_5ffb303a68cef187fa0bbd16672d28da1610896805863; BAIDUID=4D93AAC3A3CB1205043278144FDCA352:FG=1; BAIDUID_BFESS=4D93AAC3A3CB1205043278144FDCA352:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; BIDUPSID=4D93AAC3A3CB1205043278144FDCA352; PSTM=1610897551; BDRCVFR[VXHUG3ZuJnT]=mk3SLVN4HKm; delPer=0; PSINO=5; H_PS_PSSID=; BA_HECTOR=0584alalak2g04ak8p1g0aar80r; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1610896807,1610951535; __yjsv5_shitong=1.0_7_bf96750ce6e3c2775d6ff12d4dbf3b4bc889_300_1610951535893_114.238.103.53_018a390e; yjs_js_security_passport=ae192e80ccd59875d5ef5dbd8ddbfc0aadf049c9_1610951536_js; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1610951556; ab_sr=1.0.0_NmEwZGZjNDc1YThmMzM5YTM1NWNjZDBjZDdlMzAwMmU2NGQ4YWM4Yjc4ZDAxNDJlYmFkNTYzY2MwMWIyYmQxYjcyOTE3NjFlYmQ3YmRhOTcxNDQ4MWE5YTNlNjMzNzJh'
}
# 获取sign标签
def get_sign(content):
with open('baidu.js','r') as f:
rconnent=f.read()
sign=execjs.compile(rconnent).call('e',content)
return sign
#发送post请求
def parse_url(url,formdata):
try:
response=requests.post(url,data=formdata,headers=headers)
if response.status_code==200:
htmlstr=response.text
except Exception as e:
print(e.args)
print('Request Error!!!')
return htmlstr
pass
# 获取json数据
def get_jsonData(htmlStr):
jsondata=json.loads(htmlStr)
result_c={}
for item in jsondata["trans_result"]["data"]:
result_c['result']=item['dst']
return result_c
# 判断中英文
def is_chinese(uchar):
"""判断一个unicode是否是汉字"""
if uchar >= u'\u4e00' and uchar<=u'\u9fa5':
return True
else:
return False
# 处理表单数据
def dealwith_formdata(e,z,content,sign):
'''
发现发送请求之前需要识别中英文
:param e: en
:param z: zh
:param content:翻译的内容
:param sign: sign的值
:return:
'''
form = {
'from': e,
'to': z,
'query': content,
'sign': sign,
'token': 'ea5ada4109c67257a32b444d7add8f51',
}
return form
# 主函数逻辑及
def main():
en = 'en'
zh = 'zh'
url='https://fanyi.baidu.com/v2transapi'
content =input('请输入要翻译的内容【汉\英】: ')
sign=get_sign(content)
if is_chinese(content):
formdata=dealwith_formdata(zh,en,content,sign)
else:
formdata=dealwith_formdata(en,zh,content,sign)
pass
html_str = parse_url(url, formdata)
res=get_jsonData(html_str)
if is_chinese(content):
print('<{}>的英文翻译为:{}'.format(content,res['result']))
else:
print('<{}>的中文翻译为:{}'.format(content,res['result']))
pass
# 程序开关
if __name__ == '__main__':
print('-----------------xchen翻译器----------------------')
while True:
main()
三、效果展示
最后:继续加油中,互相学习交流哦!!!
奥力给。。。