細節狂魔,用 JavaScript 復原何同學B站頭圖的創意
大家好,我是大帥
,一個熱愛程式設計的老
程式猿
。
前言
在今年初,B站頒佈了2021年的百大UP。我很喜歡其中一位UP主 @老師好我叫何同學 ,他的每一個視訊都非常的有創意。
何同學也是一個極其注重細節的人,點進何同學的B站個人空間,細心的小夥伴肯定能關注到他個人空間的頭圖,右邊顯示的數字其實是何同學上次投稿距今的時間,這個數字每天都會變。
這也太細節了吧~
我並不知道何同學具體是如何實現的,但大帥
作為一個熱愛程式設計的老
程式猿
,思路很快就在我腦海裡浮現出來了。花了一天的時間敲程式碼和Debug,我已經完全實現了和何同學一樣的效果,並且無需伺服器無需開啟電腦,頭圖每天也會自動更新。
程式碼已在github
開源,如果你只是想使用它,並不想知道技術細節,請直接跳到最後看使用教學。
接下來我會手把手教你一步步去實現它,如果你想跟我一起用程式設計玩轉創意,也請點贊收藏分享支援一下吧。
本文配套視訊:https://www.bilibili.com/video/BV1bS4y1o7tM 程式碼片段
手把手實現它
好的,接下來你會學習到
- 如何抓取B站的請求
- 在nodejs裡生成圖片
- 獲得使用者最新的投稿計算日子
- GithubAction定時更新頭圖
如何抓取B站的請求
自動的前提是手動,所以我們要先了解如何手動操作才可以更換個人空間頭圖(此功能需要B站的大會員),開啟B站你的個人空間,點選頭圖右上角的這個區域更換面板
在網頁底部會彈出更換頭圖的操作面板,上傳任意圖片作為頭圖的功能只有大會員才有。
接下來常規操作,我們按下F12
開啟除錯面板,切換到network
標籤,此時我們上傳一張圖片,就可以抓取到這個上傳頭圖的介面了
auto
https://space.bilibili.com/ajax/topphoto/uploadTopPhotov2
點選滑鼠右鍵,選擇Copy -> Copy as Node.js fetch
開啟VSCode
貼上
auto
fetch("https://space.bilibili.com/ajax/topphoto/uploadTopPhotov2", { "headers": { "accept": "application/json, text/plain, */*", "accept-language": "zh-CN,zh;q=0.9", "content-type": "application/x-www-form-urlencoded", "sec-ch-ua": "\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"97\", \"Chromium\";v=\"97\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"macOS\"", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-origin", "cookie": "", "Referer": "https://space.bilibili.com/422646817", "Referrer-Policy": "no-referrer-when-downgrade" }, "body": "topphoto=xxxxxx&csrf=xxxxxx", "method": "POST"});
然後我們新建一個nodejs
的專案,安裝一下node-fetch
庫
auto
//如果你的環境支援ESModule,那麼使用importimport fetch from 'node-fetch';//如果是用require匯入const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
現在你已經可以把剛才的上傳圖片的操作通過程式碼完成了,那麼這一堆引數裡,我們需要注意哪些呢?
- cookie
使用者身份校驗的引數,我們主要會用到
bili_jct
,SESSDATA
,DedeUserID
,DedeUserID__ckMd5
- body
topphoto為圖片base64編碼的資料,
csrf
就是bili_jct
如果是自己用,那麼你只需要生成圖片並轉為base64編碼後通過topphoto
引數提交給B站介面就可以了
在nodejs裡生成圖片
在網頁裡生成圖片大概率你知道要用canvas,比如我在碼上掘金裡寫的這個demo。 程式碼片段
其實在node環境裡生成圖片,也有一個canvas的庫可以用。
auto
npm install canvas
這個庫在不同的系統下還需要安裝不同的底層繪製庫。
```auto
MacOS Xbrew install pkg-config cairo pango libpng jpeg giflib librsvg
# Linuxsudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
```
因為我不用windows,所以windows的小夥伴自己去看官方的安裝說明吧https://github.com/Automattic/node-canvas
使用這個庫繪圖的API設計和網頁canvas基本相同。
javascript
//匯入canvas庫裡的三個方法const { createCanvas, loadImage ,registerFont } = require('canvas');
//B站頭圖的建議尺寸是2560x400
const canvasSize = {w:2560,h:400};
//建立畫布const canvas = createCanvas(canvasSize.w, canvasSize.h);
//獲得畫布的繪製物件
const ctx = canvas.getContext('2d');
async function painting(){
//新增背景圖
const bgImage = await loadImage('bg.jpg');
//將圖片繪製到畫布的0,0座標,並設定寬和高
ctx.drawImage(bgImage, 0, 0, canvasSize.w, canvasSize.h);
}
painting();
有了背景圖,現在我們加入文字
javascript
//註冊字型
registerFont('digit.ttf', { family: 'digit' });
//設定文字顏色和字號,字型
ctx.fillStyle = "#e6433a";
ctx.font = '97px digit';
let txt = "HELLO"
//計算文字尺寸
let size = ctx.measureText(txt);
//將文字繪製到指定座標
ctx.fillText(txt, 0, 0);
何同學頭圖裡的文字是有垂直方向上的傾斜的,這個在canvas
中也可以實現
javascript
//設定接下來傾斜的原點為文字的左上角ctx.translate(txt_x, txt_y);
/*
transform(a,b,c,d,e,f)a 水平縮放繪圖b 水平傾斜繪圖c 垂直傾斜繪圖d 垂直縮放繪圖e 水平移動繪圖f 垂直移動繪圖
*/
ctx.transform(1,-0.3,0,1,0,0);
接下來使用canvas.toDataURL("image/png")
就可以將畫布轉換為base64
編碼的資料了,這裡需要注意一下,B站頭圖介面中的topphoto
引數是不需要前面22個字元的圖片頭資訊,所以我們還要擷取一下
javascript
canvas.toDataURL("image/png").substring(22);
當然,你現在並不能確定咱們生成的圖片是否正確,所以你也可以將圖片儲存成本地檔案先看看是不是對了
javascript
fs.writeFileSync("test.png",canvas.toBuffer());
獲得使用者最新的投稿計算日子
通過介面https://api.bilibili.com/x/space/arc/search
可以抓取指定使用者的投稿視訊
javascript
//pn為頁數,ps為每頁條數,order=pubdate代表按釋出時間返回資料
fetch("https://api.bilibili.com/x/space/arc/search?mid="+DEDEUSERID+"&pn=1&ps=1&order=pubdate&jsonp=jsonp");
在每條視訊的資訊裡,created
屬性代表了釋出時間(單位:秒),我們需要計算一下這個時間和當前系統的時間差並轉換為天為單位
javascript
//計算兩個日期相差的天數
const diffDays = (date, otherDate) => Math.ceil(Math.abs(date - otherDate) / (1000 * 60 * 60 * 24));
這裡推薦給大家一個網站,裡面收錄了各種用一行程式碼實現的功能 https://1loc.dev/
Github Action定時任務
Github Action
是Github
提供的虛擬容器服務,通俗點說就是免費給你一臺雲伺服器,這個雲伺服器的系統是什麼,具備哪些程式碼執行環境通通都可以根據配置自定義。我們通過github的工作流workflow
來使用它,有趣的是,我們還可以給它設定定時任務來定期執行我們的工作流,執行我們寫好的程式碼,生成圖片上傳一氣呵成!完全免費!
sh
開啟終端/命令列,在git專案目錄下新建目錄並建立schedule.yml配置檔案
mkdir .github
mkdir .github/workflows
touch .github/workflows/schedule.yml
schedule.yml
配置
```yaml
這個工作流的名稱
name: CI
工作流什麼時候可以執行
on: # Schedule就是定時任務,由於服務在國外,所以時間需要減去8小時才是北京時間 schedule: - cron: '0 16 * ' # 也允許這個工作流在github aciton面板中手動觸發 workflow_dispatch:
工作流內有哪些任務
jobs: # 此工作流包含一個任務名為build build: # 安裝最新的ubuntu系統 runs-on: ubuntu-latest
# 此任務重包含的子任務/步驟
steps:
# 拉取最新的程式碼
- uses: actions/checkout@v2
# 安裝好Nodejs的執行環境
- name: Setup Node.js environment
uses: actions/[email protected]
# 安裝好node canvas必備的系統繪相簿
- name: Setup Basically Packages
run:
sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
# 安裝好我們自己專案的依賴包
- name: Install NPM dependencies
run:
npm install
# 執行我們自己的程式碼
- name: Run
run:
node index.js "${{secrets.BILI_JCT}}" "${{secrets.SESSDATA}}" "${{secrets.DEDEUSERID}}" "${{secrets.DEDEUSERID__CKMD5}}"
```
配置這樣就結束了,在北京時間每天的零點(美國時間16點
)就會自動生成頭圖並上傳啦。
配置中的
secrets.xxx
是我們程式碼執行時攜帶的引數,為了讓大家更方便的fork此開源倉庫,所以我將四個B站使用者身份所對應的引數設定成了可自定義的。這種secrets
的引數在接受自定義的同時還能保護其在Github
不被洩露。
使用本專案
如果你只是想要用使用本倉庫實現一樣的效果,是非常簡單的,因為我都封裝好了,拿來即用
溫馨提示:只有B站大會員可以自定義頭圖
auto
https://github.com/ezshine/auto-bilibili-topphoto
步驟1:
fork本倉庫
步驟2:
用Chrome
瀏覽器開啟B站,進入自己的個人空間,按下F12,切換到application
標籤
在Cookie
中找到這四個引數,然後開啟自己分支倉庫,點選Settings
,進入Secrets
,點選New repository secret
將四個引數一一配置好
步驟3:
手動執行一次工作流,以後就可以自動定時運行了!
恭喜,現在你已經擁有了和何同學一樣有趣的全自動B站個人空間頭圖。
公眾號搜大帥老猿
,加入猿創營
社群,跟我一起學習用程式設計玩轉創意吧~
我正在參加「創意開發 投稿大賽」詳情請看:掘金創意開發大賽來了!
- 2022,38歲,裸辭,自由職業一年實況分享
- 太強了!外國小哥花16個月用Three.JS打造了一個無縫切地圖的3D開車遊戲
- 細節狂魔,用 JavaScript 復原何同學B站頭圖的創意
- 碼上摸金,用PIXI GSAP仿寫vanmoof剎車動效 | 猿創營
- 在uni-app中使用微軟的文字轉語音服務
- 萬馬奔騰隊的phaser3 戰疫小遊戲開發歷程回顧
- 用uni-app開發一個名為漢兜的遊戲
- 淺談對貪食蛇遊戲的一點微創新
- 手把手教你做iOS逆向分析,突破微信的群發多選數量限制
- 產品經理:你能不能用div給我畫條龍?
- 這個榜單我不服!終究還是錯付了這個綠茶掘金
- 前端摸魚神器,設計稿一鍵匯出 「小程式/Vue/Uni-app」程式碼
- 請收下這份原始碼,用Vue開發的一個“螞蟻森林澆水偷菜”遊戲
- 微信小程式統一分享,全域性接管頁面分享訊息的一些技巧
- 這45道面試可能被問到的JS判斷題!你能答對幾道?
- CSS邊玩邊學,這五個遊戲讓你對CSS的掌握更進一步!
- Web網站掃【小程式碼】登入的技術實現!記得收藏,要用時別找不到!
- 獻給所有技術內容創作者~猿創聚合助手小程式開發難點解析
- 花60秒給Vue3提的PR,竟然被尤大親自Merge了~
- 使用Vue開發“螞蟻森林澆水偷菜”遊戲的心得體會