何謂 Userscript
其實我一開始根本沒聽過這詞,而是到了某天才意識到原來自己寫的東西好像可以稱為 userscript 啊。基本上只要是在 client 端把某段 script 塞到網頁裡去改變了這網頁原本的運作、樣式或是類似爬蟲的功能,都可以稱這段 script 為 userscript
為什麼需要 userscript
追溯到我第一次寫這樣的東西,大概是對 Ingress 瘋狂的時候,為了追殺成就塔煮了坨 600 多行的義大利麵在 Ingress Intel Map 定期去紀錄全台灣每座塔 (Portal) 的 owner
然而這就是為什麼需要或為什麼會有 userscript 的原因,因為官方沒有提供使用者想要的功能 (不論何不合理或合不合法),所以只好自己來
Userscript 可以做什麼
:大部分你想要但網站本身沒有的功能,像是
1.只會 JS 的前端也想要爬資料,但沒有 API
學校教務系統沒有 Open API,但我想要所有開課資訊,這時候就可以寫段 script 塞到瀏覽器讓他幫我爬再塞進自己的 DB
你可能會說阿不就用 python 寫個爬蟲就好了,但我不會啊QQ,另外是直接在頁面塞 code 可以免於可能會遇到 CORS、登入的問題,所以就先這樣吧
2.沒朋友一起參加活動但我想要序號啊
手遊出活動,要邀請朋友參與才能拿序號換虛寶,可是邊緣人沒朋友R,所以只好再次塞東西進瀏覽器了,拿序號一時爽,一直拿序號一直爽
3.想要抓稀有神奇寶貝
Pokemon go 剛出的時候每天都為了快龍、卡比獸奔波,雖然後來有大家找寶貝、poke5566 幫忙,但常常看到的時候都來不及了,希望有即時通知啊
謎:自己做不就有了 (https://hackmd.io/s/SJOrobrA)
4.想一次看完 Dcard 文章的圖片啊
Dcard 瀏覽圖片的功能只能看同一層樓的附圖,可是我想要一次看完原文跟所有留言內的圖片,然後又一個 userscript 誕生了 (https://github.com/x3388638/dcard-images)
2020–01–10 update: 更多細節請參考下一篇 http://medium.com/@z3388638/74e292e5545b
5.用 Google 彩蛋薩諾斯彈指來回報垃圾發言
如果你還有在用知識+就知道上面不少垃圾、廣告內容,雖然檢舉流程沒有很複雜,不過由於人(ㄗˋ)類(ㄐㄧˇ)的懶墮於是弄了個一鍵檢舉的 userscript,但這樣太單調了所以又加上了薩諾斯效果。
https://github.com/x3388638/YahooAnswersSpamReport (第一次嘗試用 webpack 包了些 npm package 進來所以有點肥)
以上都只是出自於自己的需求而弄出來的東西,當然還可以找到更多實用的 userscript 來套用
如何開發 userscript
釐清需求、資料來源
首先你要知道你要達到的效果是什麼,然後會需要加入、操控哪些 UI 或是從系統、頁面中取出什麼資料,而資料的部分要怎麼取得
比方說蘋_日報不久前改成會員制,沒有登入就看不到新聞內容,但我不想要登入可是我要看新聞,所以先來研究一下新聞內容是怎麼出現或怎麼消失的,聰明如你一定很快的可以發現其實在最初 render 時新聞內容是存在的,而後才透過 JS 把內容砍掉
這下需求都釐清了:目標是讓新聞內容顯示在頁面,需要取得新聞內文,再貼於頁面中,附加頁面中有引入 jQuery,所以可以直接使用,資料來源就是頁面中 JS 還沒執行前的 .ndAtricle_margin p
內容
於是有了這樣的 code,然後貼在瀏覽器 devtool console 就算是個最基本的 userscript 了
$.get('./', data => {
const $doc = $(data);
$('.ndPaywall').remove();
$('.ndArticle_contentBox')
.html($doc.find('.ndArticle_margin p').first().html());
});
或者你想要跟 UI 有點互動也可以在按下「註冊/登入」後才顯示內文
document.querySelector('.ndPaywall input')
.addEventListener('click', e => {
$.get('./', data => {
const $doc = $(data);
$('.ndPaywall').remove();
$('.ndArticle_contentBox')
.html($doc.find('.ndArticle_margin p').first().html());
}); e.stopImmediatePropagation();
});
工具
當然總不可能每次都要手動打開 devtool 然後把 code 拿來貼,所以我們需要一些工具、資源來管理這些 userscript
自己常用的是 Tampermonkey 及 OpenUserJS,Tampermonkey 對現今主流瀏覽器都有支援,透過這個 extension 可以方便安裝、管理使用中的 userscript,然後用 OpenUserJS 來管理 userscript source code,並且能整合 GitHub webhook ,當有新 commit push 到 GitHub 時可自動推到 OpenUserJS
其他設定
除了 code 本體,還需要加一些 userscript 專用的 meta data,讓 Tampermonkey 這類 extension 可以知道這個 userscript 的資訊,像是
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://medium.com/
// @grant none
// ==/UserScript==
@match 讓 extension 知道在哪些 URL 下要執行,@grant 可以讓你存取一些方便的 function,詳細的使用方法就不多贅述,其他還有一堆欄位可以參考 Tampermonkey 文件
結論
寫 userscript 要什麼能力
說穿了 userscript 在做的事超過 87% 其實就是前端開發,所以勢必至少要對 HTML、CSS、JavaScript 有些瞭解
再來我個人認為很重要的是 trace code 的能力,為了要能夠在別人的頁面上做修改,必然要先了解相關的架構、事件綁定、流程等等,或是會需要去 call 對方的 API,而 API 當然不會有文件教你怎麼使用,這時就要找到 source code 中是怎麼呼叫 API 的及所帶的參數是怎麼產生的,此外常常要 trace 的是 minify + uglify 過的 JS
(最喜歡愛把變數設為全域的網站了)
跟開發 extension 有什麼差
總目標沒有差,就是要發大財,阿我是說要讓生活更美好、讓人類更懶惰。細節的話因為我也沒寫過 extension,不過理論上就是 extension 可以做出更強大的功能,像 Chrome extension 就能使用許多 Chrome 提供的 API,而且比較是針對瀏覽器新增功能而非針對特定網站
最後感謝你的閱讀,文中若有任何錯誤知識還請糾正,如果你喜歡這篇文章可以拍 10 次手,不喜歡的話可以拍 1 次然後分享給 5 個人