抓包工具、PyExeJs模組
在處理一些網站的時候,會遇到一些遮蔽F12,以及只要按出瀏覽器的開發者工具,就會關閉甚至當機的現象
在遇到這類網站的時候,可以使用抓包工具,把頁面上遮蔽開發者工具的程式碼給幹掉
一. Fiddler和Charles
這兩款工具是非常優秀的抓包工具。它們可以監聽到計算機上所有的http網路請求。利用這種特性,可以獲取到頁面載入過程中的所有內容
1.1 fiddler簡單配置(HTTPS)
接下來,開啟www.vmgirls.com,嘗試抓包看看,發現https的請求預設是不可用的,需要配置一下證書。
1.2 fiddler簡單使用
清理一下資訊,然後重新重新整理瀏覽器, 就看到被響應的html內容了
vmgirl之所以不可以開啟開發者工具,是因為在其html中,匯入了一個disable-devtools.js。
需要想辦法把這個東西給幹掉,只要幹掉了它,就又可以開啟F12的開發者工具了
那麼如何幹掉它呢? 這就需要了解一下fiddler和charles的工作原理了.
fiddler和charles本質,其實就是一個安裝在這臺計算機上的一個代理,就像這樣:
本質上和代理沒啥區別,但是, 由於fiddler是自己本地的軟體,那麼可以在fiddler裡對請求過來的內容,進行擷取和替換
做這樣一個事情,把vmgirls的頁面原始碼捕獲,單獨寫入一個html檔案,然後把其中的disable-devtools.js部分註釋掉.
現在這個頁面原始碼在本地了,就可以進行替換了....
接下來. 重新重新整理頁面(ctrl+shift+r) , 發現右鍵有效果了.
1.3 charles安裝和使用
charles官網: https://www.charlesproxy.com/download/
charles啟用: https://www.zzzmode.com/mytools/charles/
注意:
在windows環境下,如果出現證書不可用的情況,需要手工去windows的證書管理器中,
把Charles的證書拖拽到可信任證書那一欄,然後重啟瀏覽器和charles就可以用了
如果證書預設就可用. 就不要胡亂拖拽
window證書管理器: win+r: 輸入certlm.msc
Mac
如果想要實現請求攔截,怎麼辦?
二. PyExecJS模組
pyexecjs是一個可以執行js程式碼的一個第三方模組,其使用是非常容易上手的
但是它的執行是要依賴能執行js的第三方環境的,這裡選擇用node作為執行js的位置.
2.1 安裝Nodejs
一路下一步,修改安轉位置,最後控制檯輸入:node -v
npm -v
即可
2.2 安裝pyexecjs
pip install pyexecjs
測試一下:
import execjs
print(execjs.get().name) # Node.js (V8)
2.3 簡單使用
import execjs
print(execjs.get().name)
# execjs.eval 可以直接執行js程式碼並得到結果
js = """
"魯班_王昭君_猴子_亞瑟_蔡文姬".split("_")
"""
res = execjs.eval(js)
print(res)
# execjs.compile() 與 call()
# execjs.compile():事先載入好一段js程式碼
jj = execjs.compile("""
function an(a, b){
return a + b
}
""")
# call():執行程式碼中的xxx函式. 後續的引數是xxx的引數
ret = jj.call("an", 10, 20)
print(ret)
windows中如果出現編碼錯誤. 在引入execjs之前. 插入以下程式碼即可.
import subprocess
from functools import partial
subprocess.Popen = partial(subprocess.Popen, encoding='utf-8')
import execjs
完事兒,execjs就這幾個功能就夠咱使用
2.4 實戰案例(除錯工具)
接下來,來破解真正的百度翻譯
透過抓包可以發現:之前抓取的百度翻譯,其實是個偽翻譯
真正的一句話的翻譯,其實它的url應該是:https://fanyi.baidu.com/v2transapi?from=en&to=zh
接下來就是分析這一坨
y = {
from: d.fromLang, // 從xxxx
to: d.toLang, // 翻譯成xxxx
query: e, // 被翻譯的內容
transtype: r, // 固定的翻譯型別
simple_means_flag: 3, // 常量
sign: L(e), // ????
token: window.common.token, // token. 這個在頁面原始碼裡能找到
domain: R.getCurDomain() // 固定值.
};
現在有3個值,無法直接確定。一個是L(e)。 一個是token。另一個是R.getCurDomain()
先看 token
由於在進行翻譯的時候,頁面是沒有重新整理的,所以這個token一般在進行翻譯的時候,是不會改變的
再看 domain
在頁面中設定一個斷點,並重新傳送請求
點進去返回的是個M. 找M
OK, M是常量,"common"
最後看 L(e)
首先e是被翻譯的內容,所以這裡是把"要翻譯的內容"傳遞給了L.。但是這個L在哪裡,不好找。很簡單,設定一個斷點,就可以
程式停在這裡了,接下來就是這三個按鈕,從左到右:
第一個: 釋放掉當前debug,程式繼續向後執行,直到結束或下一個斷點
第二個: 執行下一步,相當於一行程式碼。
咱們這裡,是在一個{}中間進行的斷點。而整個{}; 被認為是一行程式碼,所以下面的 token等會被過掉
第三個: 執行到當前行內部。
咱們這裡,就是執行到L(e)裡面,看看L(e)裡面是幹什麼的
這裡就是那個L(e)了,但這東西屬實看不明白,也不容易看明白。裡面是一個簽名演算法,十分難搞
仔細觀察下,發現該函式內部只呼叫了n() a()函式。其他函式都是js內建的東西。OK 向上簡單尋找就發現了,這裡是一個大閉包
也就是說整個簽名的計算,就這些功能。沒有呼叫外界的其他功能。那就好辦了。可以直接把這個閉包內的三個函式搞出來,變成我們的js檔案
嘗試著籤個名試試看:
import requests
import execjs
f = open("bbd.js", mode="r", encoding='utf-8')
js = execjs.compile(f.read())
# execjs._exceptions.ProgramError: ReferenceError: window is not defined.
ret = js.call('e', 'love')
print(ret)
報錯了,說這裡面沒有window
確實,由於我們的js是在node裡面執行的,node是沒有window物件的. 怎麼辦?
整合起來這裡要用到window['gtk'],這玩意哪裡找? 老實說,真不好找。在前面找token的時候,偶然間,發現了這樣一段程式碼:
OK了 . 搞定... 只要把js裡面的window['gtk'],修改成這個就好了
至此, 所有引數到位. 寫程式碼就好了.
程式碼:
import requests
import execjs
f = open("baidu加密.js", mode="r", encoding='utf-8')
js = execjs.compile(f.read())
url = "https://fanyi.baidu.com/v2transapi?from=en&to=zh"
content = input("請輸入一段英文:")
data = {
"from": "en",
"to": "zh",
"query": content,
"transtype": "realtime",
"simple_means_flag": "3",
"sign": js.call("e", content),
"token": "c63d27ea65fdf259bf4d56b792e47b17",
"domain": "common",
}
headers = {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Referer": "https://fanyi.baidu.com/",
"Cookie": "REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; BIDUPSID=7214BF57BA799CC46A76979BF673523E; PSTM=1623064780; __yjs_duid=1_7946e25e70873bbe5515a663714cef991623067825398; BAIDUID=C434B9AC411BEFD0688E2DD206C8429A:FG=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; MCITY=-131%3A; BDUSS=kl4RWZySlNaNlRrdWNkSVRXYjYtNGkyUzFCZlhmeklhMDFtcjRLM01GdG4zMVZoRVFBQUFBJCQAAAAAAAAAAAEAAACh3e-019TDvczlwfnB-bjnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGdSLmFnUi5hM; BDUSS_BFESS=kl4RWZySlNaNlRrdWNkSVRXYjYtNGkyUzFCZlhmeklhMDFtcjRLM01GdG4zMVZoRVFBQUFBJCQAAAAAAAAAAAEAAACh3e-019TDvczlwfnB-bjnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGdSLmFnUi5hM; H_PS_PSSID=34438_34440_34380_34496_33848_34450_34092_34107_26350_34425_22160; delPer=0; PSINO=2; BA_HECTOR=a08k202181a52h208d1gj6e0m0q; BAIDUID_BFESS=DDAD1DC127ED72714BFB37825559ACDB:FG=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1628330239,1628390196,1629451250,1630747372; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1630747372; ab_sr=1.0.1_ODBhYjIwYzRhMjk4NDNhZDYwYjRmZWZjM2QwY2E3MGNlMDRjYTI1ZjViODM2MDgxODk5NzJjNDFkZTAxYzc0OTVkYmNhYjZiMWMzZDFmNWFkN2QxMzAwMzZlZjhjYmE3ODkxZGRkNDJkNTY2N2M0NTQxODU5YmU4YTA1NGZjYTJkMDUzN2ZkMGVkMzlmOTU1M2ZlZTRhYWY4ZDQ5YTZmNTJjYmExYzk1ZTdiY2I5MTA4YjcyZDE3MWE1MTE5YjBj",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"
}
resp = requests.post(url, data=data, headers=headers)
print(resp.json())