一虏等、小試牛刀
在上課的時(shí)候,百度翻譯之前的那個(gè)簡單的接口侈咕,需要你多次嘗試之后才能出來磕潮,其實(shí)只要我們打開network中的XHR就可以查看到翠胰。
步驟1:瀏覽器打開:fanyi.baidu.com, 按鍵順序 F12>>>Network>>>XHR。
步驟2:輸入job(在輸入過程中會(huì)不斷請求服務(wù)器)自脯,例如輸入"j"時(shí)請求之景,”jo“時(shí)請求,"job"時(shí)也在請求膏潮,如下圖:
步驟3:點(diǎn)開第3個(gè)我們可以看到url锻狗、請求方式、和請求數(shù)據(jù)焕参。
步驟4:我們開始寫爬蟲程序轻纪。
由于我們已經(jīng)看到這個(gè)接口獲取翻譯結(jié)果需要的參數(shù)很簡單,我們就以翻譯“job”為例寫爬蟲程序叠纷。
import requests
import json
def baidu_fanyi(kw):
"""
:param kw: 要查的單詞 :return:
"""
# m目標(biāo)url
base_url = "https://fanyi.baidu.com/sug"
data = {"kw":kw}
# 發(fā)起請求桐磁,返回響應(yīng)
response = requests.post(base_url,data= data)
# 獲取json數(shù)據(jù)
# 第一種 處理json數(shù)據(jù)
json_data= response.json()
# print(json_data)
data_list = json_data["data"]
for dict_data in data_list:
print(dict_data)
if __name__ == '__main__':
baidu_fanyi("job")
運(yùn)行結(jié)果是:
{'k': 'job', 'v': 'n. 職業(yè); (一件)工作; 職責(zé); (作為一個(gè)單元處理的)作業(yè) vt. 承包; 代客買賣 vi. '}
{'k': 'Jobo', 'v': '[地名] [厄瓜多爾] 霍沃'}
{'k': 'jobs', 'v': 'n. 職業(yè); (一件)工作( job的名詞復(fù)數(shù) ); 職責(zé); (作為一個(gè)單元處理的)作業(yè)'}
{'k': 'Jobs', 'v': '[人名] 喬布斯'}
{'k': 'JOBS', 'v': 'abbr. Job Opportunities and Basic Skills 工作環(huán)境與基本技能'}{'k': 'job', 'v': 'n. 職業(yè); (一件)工作; 職責(zé); (作為一個(gè)單元處理的)作業(yè) vt. 承包; 代客買賣 vi. '}{'k': 'Jobo', 'v': '[地名] [厄瓜多爾] 霍沃'}{'k': 'jobs', 'v': 'n. 職業(yè); (一件)工作( job的名詞復(fù)數(shù) ); 職責(zé); (作為一個(gè)單元處理的)作業(yè)'}{'k': 'Jobs', 'v': '[人名] 喬布斯'}{'k': 'JOBS', 'v': 'abbr. Job Opportunities and Basic Skills 工作環(huán)境與基本技能'}
二、秘密翻譯接口的參數(shù)破解
上面的你們是不是感覺太簡單了點(diǎn)讲岁,不要著急!下面這個(gè)接口請求參數(shù)才是最難破解的直接上圖衬以。
這個(gè)接口里面最難獲取的參數(shù)就是sign和token缓艳。
1、破解sign
步驟1:ctrl+F打開搜索框搜索“sign”, 找到sign所在的文件 index_e36080d.js
步驟2: 我們發(fā)現(xiàn)他是個(gè)js文件看峻,所以我們在Sources中打開index_e36080d.js阶淘。
步驟3:我們把index_e36080d.js粘貼到我們pycharm中進(jìn)行查看,搜索sign互妓。
1溪窒、剛開始我們不難的發(fā)現(xiàn)會(huì)有很多不重要的信息出現(xiàn)坤塞。
2、在搜索的過程中澈蚌,我們會(huì)發(fā)現(xiàn)sign:f(n)
3摹芙、使用ctrl+鼠標(biāo)左鍵 點(diǎn)一下f,就會(huì)轉(zhuǎn)調(diào)到下圖中的地方。
4宛瞄、f = t("translation:widget/translate/input/pGrab")中浮禾,顯然translation:widget/translate/input/pGrab
被定義為一個(gè)方法的接口路由,推測所謂的t函數(shù)可能是調(diào)用這個(gè)接口方法份汗。然后我們在pycharm中搜索translation:widget/translate/input/pGrab盈电,找到這個(gè)函數(shù)。
步驟4:我們執(zhí)行這個(gè)JavaScript函數(shù)杯活。
鑒于很多學(xué)生沒有node.js的環(huán)境匆帚,所以今天我們使用pyexecjs包來執(zhí)行js代碼。
1旁钧、安裝pyexecjs包吸重。
2、測試我們找到的函數(shù)作用均践。
(1)建立sign.js文件晤锹,把找到j(luò)s代碼粘貼進(jìn)去。
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 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)
}
(2)新建一個(gè)param_find.py開始測試js代碼彤委。但是我們不知道函數(shù)e和函數(shù)哪個(gè)是生成sign的鞭铆,我們可以在sources中進(jìn)行測試。
a. 在 sign:f(n)打個(gè)斷點(diǎn)焦影,然后刷線頁面會(huì)出現(xiàn)下圖中的情況车遂。
b .鼠標(biāo)放在f上會(huì)出現(xiàn)函數(shù)提示
c. 我們點(diǎn)擊后轉(zhuǎn)跳到函數(shù)e中,點(diǎn)擊調(diào)試按鈕開始調(diào)試斯辰。
d. 不難發(fā)現(xiàn)這個(gè)函數(shù)e就是來生成sign的舶担,這時(shí)候我們看到了“job”,說明給這個(gè)函數(shù)參數(shù)應(yīng)該是要翻譯的內(nèi)容彬呻,這樣我們就搞定了衣陶,開始寫Python代碼執(zhí)行js函數(shù)。
import execjs
def read_js(path):
with open(path, "r")as f:
f = f.read()
return f
res = execjs.compile(read_js("signa.js")).call("e", "job")
print(res)
執(zhí)行之后報(bào)錯(cuò)了 i is not defined ,說明你還要傳入i 的值320305.131321201 闸氮。
e . 通過調(diào)試js代碼發(fā)現(xiàn) i 應(yīng)該是 320305.131321201 剪况,發(fā)現(xiàn) i=window[l] 而上一行的 l,很明顯是個(gè)定值 gtk蒲跨。
需要注意的是译断,通過驗(yàn)證:查詢其他單詞 i 的值沒有變
f. 我們sign.js中加這一行代碼
var i = "320305.131321201"
g. 運(yùn)行param_find.py得到231901.486124,我們比較一下翻譯job的請求參數(shù)或悲,發(fā)現(xiàn)sign就是 231901.486124孙咪,說明我們破解了js,成功生成了sign參數(shù)堪唐。
2、破解token
還是上面的思路我們首先在network中進(jìn)行搜索token翎蹈,然后按照同樣的思路解決淮菠。
步驟1: 搜索哪些哪個(gè)文件中包含了token。
token為空表示第一次訪問百度網(wǎng)站服務(wù)器端沒有收到baiduid cookie杨蛋,會(huì)導(dǎo)致翻譯接口校驗(yàn)不通過兜材,通過刷新解決
1、獲取這個(gè)js文件逞力。我們發(fā)現(xiàn)他其實(shí)可以通過請求https://fanyi.baidu.com/曙寡,這個(gè)鏈接獲取html文件。
通過正則來獲取如下js文件token的值
具體代碼如下:
import re
import requests
import execjs
url = "https://fanyi.baidu.com"
headers = {
"Cookie": "BIDUPSID=EE1FBAB64E978CA7E15A21204784E059; PSTM=1574385249; MCITY=-233:; BAIDUID=8FE349D493E4028413DDDC33C39D13B2:FG=1; __yjs_duid=1_eb4f55bc190bb694fbbccd0271c4cce61614069225050; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; PSINO=2; BAIDUID_BFESS=BAF37D17762844A4E0C7143382B922B2:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; H_PS_PSSID=33636_33256_33272_33709_33689_33595_33590_26350; ZD_ENTRY=baidu; BA_HECTOR=0la02ga1818l2ga4v31g58k0l0r; BCLID=10547301397971942590; BDSFRCVID=LMIOJexroG3VC5QeobuohXPMALweG7bTDYLEOwXPsp3LGJLVJeC6EG0Pts1-dEu-EHtdogKK0gOTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tJKJoCtatD_3fP36qR6sMJ8thmT22-us5Cnd2hcH0KLKEpnGWhoDbt4UKGj3XpOuJIjiaMjwWfb1MRjvh-LhefCN547QBTbd-H5bol5TtUJceCnTDMRh-lIZMb5yKMniMRr9-pPX3pQrh459XP68bTkA5bjZKxtq3mkjbPbDfn02eCKuDjRDKICV-frb-C62aKDshJTgBhcqJ-ovQTb4LTLubfni36Q3yNRu_P555l0bHxbeWfvpXn-R0hbjJM7xWeJpaJ5nJq5nhMJmKTLVbML0qto7-P3y523ion3vQpP-OpQ3DRoWXPIqbN7P-p5Z5mAqKl0MLPbtbb0xXj_0D6c3DG0Ht5Lsb5vfstcS24JED6rnhPF3hM-mXP6-35KHyH783fbt5R7vEfndWh3Yj-uUynQkBq37JD6y2UQOQ-JJSDQL0Ic_M6JXhtoxJpOgMnbMopvaKfcooqRvbURv2jDg3-A80U5dtjTO2bc_5KnlfMQ_bf--QfbQ0hOhqP-j5JIEoCvt-5rDHJTg5DTjhPrMK4QRWMT-MTryKKOC0KKheJA4LfosWh8IjhofKx-fKHnRhlR2B-3iV-OxDUvnyxAZyxomtfQxtNRJQKDE5p5hKq5S5-OobUPUDMJ9LUkqW2cdot5yBbc8eIna5hjkbfJBQttjQn3hfIkj2CKLtCvDqTrP-trf5DCShUFs-UbWB2Q-XPoO3KO4EI5hbtPKhl4JWb3utnQf5mkf3fbgylRp8P3y0bb2DUA1y4vpBtQmJeTxoUJ2-KDVeh5Gqfo15-0ebPRiJPb9Qg-qahQ7tt5W8ncFbT7l5hKpbt-q0x-jLTnhVn0MBCK0hDvPKITD-tFO5eT22-usBgjA2hcHMPoosIOKLToGbt4V5fn3XpOu0mJf0l05KfbUoqRHXnJi0btQDPvxBf7pWDTm_q5TtUJMqIDzbMohqfLn5MOyKMnitIv9-pPKWhQrh459XP68bTkA5bjZKxtq3mkjbPbDfn028DKu-n5jHjJyeH8j3J; BCLID_BFESS=10547301397971942590; BDSFRCVID_BFESS=LMIOJexroG3VC5QeobuohXPMALweG7bTDYLEOwXPsp3LGJLVJeC6EG0Pts1-dEu-EHtdogKK0gOTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF_BFESS=tJKJoCtatD_3fP36qR6sMJ8thmT22-us5Cnd2hcH0KLKEpnGWhoDbt4UKGj3XpOuJIjiaMjwWfb1MRjvh-LhefCN547QBTbd-H5bol5TtUJceCnTDMRh-lIZMb5yKMniMRr9-pPX3pQrh459XP68bTkA5bjZKxtq3mkjbPbDfn02eCKuDjRDKICV-frb-C62aKDshJTgBhcqJ-ovQTb4LTLubfni36Q3yNRu_P555l0bHxbeWfvpXn-R0hbjJM7xWeJpaJ5nJq5nhMJmKTLVbML0qto7-P3y523ion3vQpP-OpQ3DRoWXPIqbN7P-p5Z5mAqKl0MLPbtbb0xXj_0D6c3DG0Ht5Lsb5vfstcS24JED6rnhPF3hM-mXP6-35KHyH783fbt5R7vEfndWh3Yj-uUynQkBq37JD6y2UQOQ-JJSDQL0Ic_M6JXhtoxJpOgMnbMopvaKfcooqRvbURv2jDg3-A80U5dtjTO2bc_5KnlfMQ_bf--QfbQ0hOhqP-j5JIEoCvt-5rDHJTg5DTjhPrMK4QRWMT-MTryKKOC0KKheJA4LfosWh8IjhofKx-fKHnRhlR2B-3iV-OxDUvnyxAZyxomtfQxtNRJQKDE5p5hKq5S5-OobUPUDMJ9LUkqW2cdot5yBbc8eIna5hjkbfJBQttjQn3hfIkj2CKLtCvDqTrP-trf5DCShUFs-UbWB2Q-XPoO3KO4EI5hbtPKhl4JWb3utnQf5mkf3fbgylRp8P3y0bb2DUA1y4vpBtQmJeTxoUJ2-KDVeh5Gqfo15-0ebPRiJPb9Qg-qahQ7tt5W8ncFbT7l5hKpbt-q0x-jLTnhVn0MBCK0hDvPKITD-tFO5eT22-usBgjA2hcHMPoosIOKLToGbt4V5fn3XpOu0mJf0l05KfbUoqRHXnJi0btQDPvxBf7pWDTm_q5TtUJMqIDzbMohqfLn5MOyKMnitIv9-pPKWhQrh459XP68bTkA5bjZKxtq3mkjbPbDfn028DKu-n5jHjJyeH8j3J; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1616109895,1616110171,1616114964,1616138265; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1616138526; ab_sr=1.0.0_NmFiZmE4ZDBiODNkMjA5YTYwYmQyODExOWNlNjgwYjhkNGE4NTlmNWZmNDBmNTIwYzQxZmEyMzMyOWM0ZjA2ZjkyZDlhMGQ5YTI2YjIxYjljNjFmOTE4MzhjOWNiNjI1; __yjsv5_shitong=1.0_7_80992e39d5bba9b7737d7e4cc0e4876b0f75_300_1616138529336_124.114.149.34_63e643e3",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36",
}
html = requests.get(url,headers=headers).text
# print(html)
res = re.findall("<script>(.*?)</script>",html,re.S)
print(res[2])
res1 = re.findall(" token:(.*)systime:",res[2],re.S)
token = res1[0].strip().strip("'").strip("',")
print(token)
到現(xiàn)在我們已經(jīng)破解百度翻譯的加密請求參數(shù)寇荧。
想獲取爬蟲源碼举庶,請關(guān)注微信公眾號:梓棟Code,回復(fù)“baidu”揩抡,獲取源碼户侥。
三、json數(shù)據(jù)處理
把json數(shù)據(jù)進(jìn)行解析峦嗤,獲取我們需要的結(jié)果蕊唐。
處理的方法代碼如下:
def processing_json(self):
"""處理json數(shù)據(jù)"""
with open(f"{self.query}.json","r",encoding="utf-8")as f:
res = f.read()
json_data = json.loads(res)
# print(json_data)
for _json in json_data["dict_result"]["synonym"][0]["synonyms"]:
print(_json["bx"])
res = _json["syn"].get("d")[0]
if isinstance(res,dict):
print(res["text"])
else:
print(res)
explain = json_data["liju_result"]["tag"]
explains = "-".join(explain)
print(explains)