抱歉,没忍住,终于还是对百度翻译下手了······

python爬虫:终于还是对百度翻译下手了_百度翻译
废话不多说,直接进入主题吧

python爬虫:终于还是对百度翻译下手了_百度翻译_02


按F12,直接进入开发者模式进行分析

python爬虫:终于还是对百度翻译下手了_百度翻译_03

当我们点击"翻译"按钮时,会动态加载出两个文件,其中一个文件是我们所需要的

python爬虫:终于还是对百度翻译下手了_百度翻译_04

我们点开第二个文件,查看文件内容,其文件内容就包含我们所需要的翻译结果

知道翻译结果在哪个文件,接下来就要对这个文件进一步分析

首先查看文件的url

(敲黑板)这里强调一下,汉译英和英译汉文件中的url是不同的
python爬虫:终于还是对百度翻译下手了_百度翻译_05

python爬虫:终于还是对百度翻译下手了_百度翻译_06

接下来就是文件的参数

(敲黑板)这里强调一下,汉译英和英译汉文件中的参数是不同的
python爬虫:终于还是对百度翻译下手了_百度翻译_07

python爬虫:终于还是对百度翻译下手了_百度翻译_08

知道这些,我们先简单写一段代码来验证一下,看能否请求到结果,代码如下:

python爬虫:终于还是对百度翻译下手了_百度翻译_09
我们可以看到,使用文件的url和参数是可以获取到数据的

到这里有人会问了:既然如此简单的话,那我们将参数中要翻译的内容换成其他的不就可以得到不同数据了吗,easy,完结。

等等~~
python爬虫:终于还是对百度翻译下手了_百度翻译_10

事情果真如此吗,我们试一下:

python爬虫:终于还是对百度翻译下手了_百度翻译_11

上面的代码我只修改了翻译内容参数,其他的都原封不动,执行完成之后结果却报错了,怎样,事情没有你们想的那么简单吧(我才不会告诉你们我也是这么想的)

python爬虫:终于还是对百度翻译下手了_百度翻译_12

那我们就要验证一下到底是哪里出了问题,我们对"nice"这个单词进行翻译,查看参数:

python爬虫:终于还是对百度翻译下手了_百度翻译_13

和上一个单词的参数进行比较,我们可以发现,两个结果中"sign"参数的值是不同的,那我们也知道为什么上面的请求会出现error了,接下来我又翻译了几个单词,发现他们结果中的"sign"参数的值都是不同的,也就是每个不同的翻译对应不同的sign值

既然知道问题是出在这个参数身上,那我们接下来可以从这个参数入手,在加载的全部文件中搜索参数sign的值,结果找不到,看来这个值是动态生成的,思考ing······

python爬虫:终于还是对百度翻译下手了_百度翻译_14

通过参考其他大佬的文章,找到了解决办法,我们可以将动态生成sign值的那部分js代码单独拿出来运行,这样我们就可以获取动态生成的sign值

python爬虫:终于还是对百度翻译下手了_百度翻译_15

动态生成sign值的代码(JavaScript文件):

function n(r, o) {for (var t = 0; t < o.length - 2; t += 3) {var a = o.charAt(t + 2);a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a), a = "+" === o.charAt(t + 1) ? r >>> a : r << a, r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a}return r}function e(r) {var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);var i = "320305.131321201";if (null === o) {var t = r.length;t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10))} else {for (var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++) "" !== e[C] && f.push.apply(f, a(e[C].split(""))), C !== h - 1 && f.push(o[C]);var g = f.length;g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(-10).join(""))}var u = void 0, l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107);u = null !== i ? i : (i = window[l] || "") || "";for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) {var A = r.charCodeAt(v);128 > A ? S[c++] = A : (2048 > A ? S[c++] = A >> 6 | 192 : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? (A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v)), S[c++] = A >> 18 | 240, S[c++] = A >> 12 & 63 | 128) : S[c++] = A >> 12 | 224, S[c++] = A >> 6 & 63 | 128), S[c++] = 63 & A | 128)}for (var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++) p += S[b], p = n(p, F);return p = n(p, D), p ^= s, 0 > p && (p = (2147483647 & p) + 2147483648), p %= 1e6, p.toString() + "." + (p ^ m)}

python爬虫:终于还是对百度翻译下手了_百度翻译_16

接下来我们尝试一下获取动态生成的sign值,并添加到参数中进行请求,看能否成功获取到数据

python爬虫:终于还是对百度翻译下手了_百度翻译_17

成功获取到数据,说明这种方法是可行的

接下来我们对代码进一步的完善,使其能够从请求得到的数据中提取出翻译结果,大致效果如下:

python爬虫:终于还是对百度翻译下手了_百度翻译_18

python爬虫:终于还是对百度翻译下手了_百度翻译_19

上面我只对翻译结果进行了提取,还有很多数据也是我们需要的,比如单词的比较级,最高级,例句等等,可以根据需要进行提取

源代码:

import requestsimport execjsimport json

result = Trueheaders = {'Cookie': 'BAIDUID=2DB1AFA0F846F42901047AED8B33E89D:FG=1; BAIDUID_BFESS=2DB1AFA0F846F42901047AED8B33E89D:FG=1; __yjs_duid=1_0faee1072060aa9da16e45836d86a0401616929924749; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1616929926; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1616929927; __yjsv5_shitong=1.0_7_2b075ac61e99db24c5ec74a3d00655137508_300_1616929925818_219.146.214.92_2235fd8a; ab_sr=1.0.0_YzAwY2E0NTI5MjBiYmNhNjQ2Y2VmNDljMGU4MjgyYmM5ZTYxNjUwYzI2ZTlkZDAyZjMxNDIxODU5Y2RhNzE0YTRkOTVlM2Y1ZmIyOTc5OWQ4YzYzY2NkZjdjYjEyZjA4','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36'}with open("sign.js","r") as f:s = f.read()# 为参数动态赋值def setparameter(input,p_from,p_to):global formdata# 获取动态生成的sign值# 第一个参数默认,第二个参数是我们要翻译的内容sign = execjs.compile(s).call("e", input)formdata = {'from': p_from,'to': p_to,'query': input,'transtype': 'translang','sign': sign,'simple_means_flag': 3,'token': '2b05b729bcef9ccb94cf5d6ea7154362','domain': 'common'}# 获取数据,提取翻译结果def translate(input):if result == True:parameter_from = "zh"parameter_to = "en"url = "https://fanyi.baidu.com/v2transapi?from=zh&to=en"  # 中文译为英文else:parameter_from = "en"parameter_to = "zh"url = "https://fanyi.baidu.com/v2transapi?from=en&to=zh"  # 英文译为中文setparameter(input,parameter_from,parameter_to)html = requests.post(url,data = formdata,headers=headers).text
    html = json.loads(html)results = html['liju_result']['tag']  #  提取翻译结果print("翻译结果:")for get in results:print(get)# 程序入口def main():global result
    userinput = input("请输入需要翻译的内容:")# 判断用户输入是否为中文,若为中文执行汉译英,若为英文执行英译汉for ch in userinput:if '\u4e00' <= ch <= '\u9fff':result = Trueelse:result = Falsetranslate(userinput)main()

我也准备写一个完整的版本,能够展示更多有用的信息,最好再加一个图形界面,嗯,下次见吧

python爬虫:终于还是对百度翻译下手了_百度翻译_20