利用猴子給目標網站安裝業務模組外掛

利用猴子給目標網站安裝業務模組外掛

文中只是拿小程式做例子,你可以套用到想用的任何地方。

場景

你們有個產品是基於微信小程式的,然後呢,微信小程式後臺有相關的資料支撐,一般顯示如下:

利用猴子給目標網站安裝業務模組外掛

微信小程式預設後臺

稍微有一些規模的小程式,一般來說可能會接入各種亂七八糟的埋點方案,然後,我們自己也有一套與之對應的後臺管理(資料後臺)。

這個時候,作妖的業務方來了,跟產品說,我們希望把微信後臺的一些資料整合到我們自己的資料中臺去……

問題

這個需求可行嗎?有一些爬蟲經驗的小夥伴可能就要說了,行是行,但是成本太高了。

作為一名聽說過爬蟲的你,可能就迷惑了,這怎麼做?爬微信後臺的資料嗎?

一來,資料介面是加密的;二來,要死的微信後臺,時不時把你踢出去;三來,恐怕不想面向監獄程式設計吧。

這也是為什麼成本高的原因,資料不好獲取,不定時提出登入狀態還需要掃碼登入(只能掃碼,不能長按識別哦,你可以試試看),非公開資料如果被公開還有可能進局子。

就在大家一籌莫展,準備讓苦逼的業務方繼續在兩個平臺跳來跳去的時候,你們的資深前端說了句,“你們是不是太小看前端了?”

解決方案

其實說起來,解決方案很簡單,只是在於你是否這麼搞過而已。

首先,我們開啟控制檯,解析一下這個頁面的標籤結構:

利用猴子給目標網站安裝業務模組外掛

你會發現,這個資料塊的 class 是

mod_default_box,並且為了保險,你還重新整理了,發現沒變,於是乎,你就想到了,我自己去繪製一個塊,然後放到它前面(後面一樣)不就好了,然後拿到資料填充進去,嘿!我不能爬你微信後臺資料,還不能讓我自己把資料插到你的後臺裡面嘛?

你一拍桌子,我去……妙啊!

利用猴子給目標網站安裝業務模組外掛

先是 querySelectorAll(‘。mod_default_box’) 找到第二個是你的目標。

利用猴子給目標網站安裝業務模組外掛

吶,你要的益達,不對,你要的模組來了。

這裡是偷懶,因為我不知道你是什麼鬼業務,所以這裡複製了一份以假亂真。你自然是根據自己需要的

業務來手寫 HTML 了。

為了搞得更像一點,我做了一點點修改,如下:

利用猴子給目標網站安裝業務模組外掛

是不是看出來差異了?

到此你拿到了第一份可用的程式碼:

let wx_module = document。querySelectorAll(‘。mod_default_box’)[1]// 以下根據業務特殊處理let new_moduel = wx_module。cloneNode(true)wx_module。insertAdjacentElement(‘beforeBegin’, new_moduel)new_moduel。querySelector(‘h4’)。innerText = ‘我就是個Demo’

還剩下兩個問題:

不可能每次進來都需要複製這份程式碼吧,業務方那些技術小白也不會啊

介面呢?我要拿資料啊

別急,還有。

掃尾處理

問題一,複製程式碼這個事情肯定很傻,我們需要做到的是,不需要開啟控制檯,不需要 Ctrl + V 就可以直接執行,那麼為了方便,我們加個

alert('我是自動執行')

來標記下。

忘了說了,你想自動,就得給業務方使用人員安裝下外掛,這個沒辦法……

利用猴子給目標網站安裝業務模組外掛

如果你是個前端,相信對 FeHelper 應該很熟悉,他有自帶的油猴工具,當然了,你也可以去下載老油猴,這個隨便你,我只是懶得裝太多,就用一個了,老油猴這樣的:

利用猴子給目標網站安裝業務模組外掛

這是 Edge 的搜尋結果,如果你用的是 Chrome ,請自行處理。

我們拿 FeHelper 的面板舉例子:

利用猴子給目標網站安裝業務模組外掛

除了隨便取的名字外,最底下的就是程式碼,上面框框標記的是匹配的地址,支援萬用字元。

因為微信小程式後臺首頁的連結是這樣的:https://mp。weixin。qq。com/wxamp/index/index?lang=zh_CN&token=xxxxxxxx

通配成 https://mp。weixin。qq。com/wxamp/index/index* 這樣,就意味著,哪怕token重新整理了或其他語言,都可以執行。

當然,你也可以直接一個*號,不過那樣就所有頁面都會執行,就很奇怪。

ok,我們關閉偵錯程式,重新整理頁面看看:

利用猴子給目標網站安裝業務模組外掛

好像行了……

但是你點選確認後,發現,沒卵用,這個原因可以從頁面看出來,你的指令碼運行了,但是目標模組還沒有,所以你複製錯了,不信你往下拉,你會發現,指令碼是有bug的。

利用猴子給目標網站安裝業務模組外掛

因為 document。querySelectorAll(‘。mod_default_box’)[1] 不安全,導致拿錯資料了,我們再進行《一點點》最佳化:

(() => { function handler() { // 以下根據業務特殊處理 let wx_module = document。querySelectorAll(‘。mod_default_box’)[1] let new_moduel = wx_module。cloneNode(true) wx_module。insertAdjacentElement(‘beforeBegin’, new_moduel) new_moduel。querySelector(‘h4’)。innerText = ‘我就是個Demo’ alert(‘我是自動執行’) } let interval = setInterval(() => { let wx_modules = document。querySelectorAll(‘。mod_default_box’) // 這種 === 4 的程式碼都是不健壯的,根據具體業務處理,這裡僅僅是示例 if (wx_modules。length === 4) { clearInterval(interval) handler() } }, 1000)})()

說白了,就是一秒查一次,是不是跟我業務匹配(我這裡 Demo 的業務就是發現有四個模組),沒匹配即繼續查,匹配了,就執行業務程式碼。

利用猴子給目標網站安裝業務模組外掛

問題二

這個實際需要你們後端支援,放開 CORS 的跨域設定(建議單獨給目標網站放開,如這裡的微信小程式後臺)。

我在這裡模擬下不考慮跨域的情況,就是直接 GET 來請求這個網頁的 HTML 檔案內容。

(() => { function handler() { // 以下根據業務特殊處理 let wx_module = document。querySelectorAll(‘。mod_default_box’)[1] let new_moduel = wx_module。cloneNode(true) wx_module。insertAdjacentElement(‘beforeBegin’, new_moduel) new_moduel。querySelector(‘h4’)。innerText = ‘我就是個Demo’ alert(‘我是自動執行’) fetch(location。href)。then(ret => ret。text())。then(text => new_moduel。querySelector(‘h4’)。innerText = text。slice(0, 15)) } let interval = setInterval(() => { let wx_modules = document。querySelectorAll(‘。mod_default_box’) // 這種 === 4 的程式碼都是不健壯的,根據具體業務處理,這裡僅僅是示例 if (wx_modules。length === 4) { clearInterval(interval) handler() } }, 1000)})()

注意“我就是個Demo”這裡的變化,後面填充的內容是請求的 HTML 文件的字元。

利用猴子給目標網站安裝業務模組外掛

搞定!!!

總結

其實很簡單,主要還是你能不能想到這個方案,並且善用工具而已。