百度翻譯之爬蟲js逆向解析

第一步分析網頁
打開頁面之后,摁F12,打開開發(fā)者工具,在文本框中輸入想要翻譯的詞匯

這時,就能看到network中的請求響應:

https://fanyi.baidu.com/v2transapi?from=zh&to=en,請求方式為post,
鼠標往下移動,能看到請求自帶Form Data的參數:

再重復一次操作:

就能得出兩次請求所帶的參數的不同之處。
想要得到動態(tài)sign的數據,需要點擊下圖選項,在參數中選擇一個參數放到search中,然后點擊處于藍色方框的simple_means_flag


把鼠標移到sign: L(e)的這行的行數8392中點擊,打上斷點,在頁面再點擊一次翻譯,就會顯示出前端的數據,把鼠標移到L,他會顯示出一個函數的調用,點擊進入函數


可以看得出來傳入函數的型參r就是我們在頁面輸入的需要翻譯字符, 點擊下圖紅框選項,讓它執(zhí)行下一行,就會把參數顯示出來了


第二步 開始寫爬蟲程序
在pycharm的終端中下載第三方庫?PyExecJS,jsonpath, requests



先寫一個用戶代理隨機分配的函數

建立自定義的爬蟲函數

在請求頭(request headers)中找到User-Agent,? Cookie,? Referer, 復制里面的值下來到文件中,用來應對反爬策略


運行代碼查看結果

跳出報錯信息,知道了 i 未定義,主函數中并沒有 i 這個變量, 于是把目標轉移到網頁當中選中watch點擊+直接輸入??i? 點擊+旁邊的刷新,就能得到數據

在js文件中添加上這個參數

再試試打印結果

在watch這種輸入n,得出的結果是 n ( r? , o )

把鼠標移到 p = (D , F), 點擊進去直接黃色黃色高亮會跳到n?(?r??,?o?)的函數

把這段代碼復制下來,放到js文件中

最后再運行下代碼

得到sign的參數, 使用變量接收,并把它放到字典中保存

使用requests的方法post開始爬取數據

使用jsonpath的方法解析json數據, 運行結果得出翻譯結果


完整爬蟲代碼
def User_Agent():
? ?import random
? ?User_Agent_list = [
? ? ? ?"Mozilla/5.0 (Windows NT 6.1; WOW64) appleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"
? ? ? ?"Mozilla/5.0 (X11; CrOS i686 2268.111.0) appleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
? ? ? ?"Mozilla/5.0 (Windows NT 6.1; WOW64) appleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
? ? ? ?"Mozilla/5.0 (Windows NT 6.2) appleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
? ? ? ?"Mozilla/5.0 (Windows NT 6.2; WOW64) appleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
? ? ? ?"Mozilla/5.0 (X11; Linux x86_64) appleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
? ? ? ?"Mozilla/5.0 (Windows NT 6.0) appleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
? ? ? ?"Mozilla/5.0 (Windows NT 6.1; WOW64) appleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
? ? ? ?"Mozilla/5.0 (Windows NT 5.1) appleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
? ? ? ?"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) appleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
? ? ? ?"Mozilla/5.0 (Windows NT 6.2) appleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
? ? ? ?"Mozilla/5.0 (Windows NT 6.1; WOW64) appleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
? ? ? ?"Mozilla/5.0 (Windows NT 6.2) appleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
? ? ? ?"Mozilla/5.0 (Windows NT 6.1; WOW64) appleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
? ? ? ?"Mozilla/5.0 (Windows NT 6.1) appleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
? ? ? ?"Mozilla/5.0 (Windows NT 6.2) appleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
? ? ? ?"Mozilla/5.0 (X11; Linux x86_64) appleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
? ? ? ?"Mozilla/5.0 (Windows NT 6.2; WOW64) appleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
? ?]
? ?return random.choices(User_Agent_list)[-1]
def baidu_fanyi():
? ?from jsonpath import jsonpath
? ?import execjs ?# 導入執(zhí)行js文件的第三方庫
? ?# 百度翻譯
? ?url = "https://fanyi.baidu.com/v2transapi?from=zh&to=en"
? ?# 請求頭
? ?header = {
? ? ? ?# 用戶代理
? ? ? ?'user-agent': User_Agent(),
? ? ? ?# 跳轉網址
? ? ? ?'referer': "https://fanyi.baidu.com/",
? ? ? ?# 會話記錄
? ? ? ?'cookie': "PSTM=1624889671; BDRCVFR[IZdXtXdDRBm]=EBD6F1bEM2tXZKdrHn8mvqV; BA"
? ? ? ? ? ? ? ? ?"IDUID=A40ADC4C6BA4061C4246C9BE890ADBCA:FG=1; H_PS_PSSID=; BIDUPSID"
? ? ? ? ? ? ? ? ?"=DF100614A15524BC80AF12360E70B2FE; Hm_lvt_64ecd82404c51e03dc91cb9e8"
? ? ? ? ? ? ? ? ?"c025574=1625065330; __yjs_duid=1_a8b2eaa3041ec1e82854c53f970c651c162"
? ? ? ? ? ? ? ? ?"5065329951; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SW"
? ? ? ? ? ? ? ? ?"ITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; Hm_lpvt_64ecd82404"
? ? ? ? ? ? ? ? ?"c51e03dc91cb9e8c025574=1625838257; ab_sr=1.0.1_NzM2MDM1OTRkNmFkN2RlYz"
? ? ? ? ? ? ? ? ?"kwNzYwMzYxYmQ4ZjFhZTNlOGI5ZDliMjRhZTRiODUzMzY5MDIxODcxM2YxZWQwNWY0ZmY"
? ? ? ? ? ? ? ? ?"0NTU4ODRjN2M3MjkwYWIyZWU2ZTcxODE3OWQ5MDM0M2IzZWZhNjkyNDgwN2RkNTU1YTI"
? ? ? ? ? ? ? ? ?"zN2RhYzM1NzMyZTU4OGFkOWNlMjNhYWEwMzc4MzcyNWIxNzM1NTg5ZA==; __yjs_st="
? ? ? ? ? ? ? ? ?"_Nzc4MmU3Mzk2NDRiYjA4ZTQ4YzY3NjQ3MGZlZmY5OWQ2OThjOTJhZjg2MGUzNjc2NTd"
? ? ? ? ? ? ? ? ?"mN2Y2OTMwYTlhZWJlOGUxOTAwY2E1OTY3MDY3YTg2ZDMwMDYxNTc2OTI4ZjRlNzlmODU"
? ? ? ? ? ? ? ? ?"5NDIzMjdkYzJjYzQ3YWRkOTY3ODJiZDc4NTVjYmQxZWE5ZmRjNjYyOGQ5OWNkZTRmZmY"
? ? ? ? ? ? ? ? ?"5OTk0YWE1OTk1MmEzYWZiN2Y0ZWFjYzI5YTFmMTAzY2Q2OWMyMWJmNzY1YWFmM2ZjYjJ"
? ? ? ? ? ? ? ? ?"mMDg2OTYyNTMzNDRlZjE4YzY2MmFmNDU4ZTdhMWRhODIzY2U1OWM4MWIwYzMzY2E2ZW"
? ? ? ? ? ? ? ? ?"RjYl83XzUxM2E1Yzhk",
? ?}
? ?query = str(input("請輸入要翻譯的關鍵詞: "))
? ?# 讀取js文件
? ?with open('fanyi_baidu_com.js', 'r') as r:
? ? ? ?read = r.read()
? ?# 使用變量接收js第三方庫的方法,并接收讀取到的js文件
? ?exe = execjs.compile(read)
? ?sign = exe.call("e", query) ?# 執(zhí)行js文件
? ?print(sign)
? ?# 參數
? ?data = {
? ?'from': 'zh',
? ?'to': 'en',
? ?'query': query,
? ?'transtype': 'realtime',
? ?'simple_means_flag': '3',
? ?'sign': sign,
? ?'token': 'a8e3ac80bd327c34add38ea58ffbcef1',
? ?'domain': 'common',
? ?}
? ?# print(data)
? ?res = requests.post(url, data=data, headers=header).json()
? ?print(jsonpath(res, "$..dst")[0])
完整js文件
? ?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);
? ? ? ?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 i = "320305.131321201";
? ? ? ?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)
? ?};