I used programming to "crack" the secret of details crazy devil he

Posted by eduard on Thu, 03 Mar 2022 05:52:29 +0100

Hello, I'm dashai, an old programmer.


Recently, station B has just announced the top 100 UP in 2021. If I want to say my favorite UP, it must be @ good teacher. My name is he classmate. Every video of he made me feel amazing and creative.

Classmate he is also a person who pays great attention to details. I don't know if you have paid attention to the head map of personal space of station B of classmate he. The number displayed on the right is the time since he submitted his last contribution, which will change every day.


It's really a detail maniac~

I don't know how he realized it, but as an old programming ape who loves programming, the idea soon came to my mind. After a day of crazy code typing, I have fully achieved the same effect as he. I don't need to open the computer without a server. It will be updated automatically every day. The code is open source in github. If you just want to use it and don't want to know the technical details, please skip to the last to see the use teaching.

This article will teach you to realize it step by step. If you want to use programming to play with creativity with me, please like it, share it and support it.

Do it hand in hand

OK, next you will learn

  • How to grab the request from station B
  • Generate pictures in nodejs
  • Get the latest submission calculation date of the user
  • github action scheduled task

How to grab the request from station B

The premise of automatic is manual, so we need to know how to operate before we can change the personal space header map (this function requires large members of station B). Open your personal space at station B and click this area in the upper right corner of the header map to change the skin

The operation panel for changing the header will pop up at the bottom of the web page. Only large members can upload any picture as the header.

We press F12 to open the debugging panel and switch to the network tab. At this time, we can upload a picture and grab the interface of the upload header


Right click and select Copy - > copy as node js fetch

Open VSCode paste

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"


Then we create a new nodejs project and install the node fetch library

//If your environment supports ESModule, use import
import fetch from 'node-fetch';

//If it is imported with require
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));

Now that you can complete the operation of uploading pictures just now through code, what should we pay attention to in this pile of parameters?

  • cookie

For the parameters of user identity verification, we will mainly use bili_jct,SESSDATA,DedeUserID, DedeUserID__ckMd5

  • body

topphoto is the data encoded by base64. csrf is bili_jct

If it is for your own use, you only need to generate the picture, convert it to base64 coding, and submit it to the interface of station B through the topphoto parameter

Generate pictures in nodejs

You know that you need to use canvas to generate pictures in the web page. There is also a library of canvas to generate pictures in the node environment

npm install canvas

This library needs to install different underlying drawing libraries under different systems.

# MacOS X
`brew install pkg-config cairo pango libpng jpeg giflib librsvg`

# Linux
`sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev`

Because I seldom use windows, my friends of windows go to see the official introduction by themselves, https://github.com/Automattic/node-canvas

The API design of drawing using this library is basically the same as that of Web canvas.

//Three methods of importing into canvas Library
const { createCanvas, loadImage ,registerFont } = require('canvas');

//The recommended size of station B is 2560x400
const canvasSize = {w:2560,h:400};
//Create canvas
const canvas = createCanvas(canvasSize.w, canvasSize.h);
//Get the painting object of the canvas
const ctx = canvas.getContext('2d');

async function painting(){
 //Add background image
 const bgImage = await loadImage('bg.jpg');
 //Draw the picture to the 0,0 coordinates of the canvas and set the width and height
 ctx.drawImage(bgImage, 0, 0, canvasSize.w, canvasSize.h);


With the background image, now let's add text

//Register font
registerFont('digit.ttf', { family: 'digit' });
//Set text color, font size and font
ctx.fillStyle = "#e6433a";
ctx.font = '97px digit';

let txt = "HELLO"

//Calculate text size
let size = ctx.measureText(txt);

//Draws text to the specified coordinates
ctx.fillText(txt, 0, 0);


The text in Mr. He's head picture is inclined in the vertical direction, which can also be realized in canvas

//Set the origin of the next tilt to the upper left corner of the text
ctx.translate(txt_x, txt_y);

a Scale drawing horizontally
b Horizontal tilt drawing
c Vertical tilt drawing
d Scale drawing vertically
e Move drawing horizontally
f Move drawing vertically

The transform tilt algorithm is a little complicated. We will teach you a separate tutorial in the future. If you want to learn, remember to pay attention and don't get lost~

Next, use canvas Todataurl ("image / PNG") can convert the canvas into base64 encoded data. Note here that the topphoto parameter in the header interface of station B does not need the picture header information of the first 22 characters, so we need to intercept it


Of course, you are not sure whether the picture we generated is correct, so you can also save the picture as a local file to see if it is right


Get the latest submission calculation date of the user

Through interface https://api.bilibili.com/x/space/arc/search You can capture the submission video of the specified user

//pn is the number of pages, ps is the number of entries per page, and order=pubdate represents the data returned according to the publishing time

In the information of each video, the created attribute represents the release time (unit: seconds). We need to calculate the time difference between this time and the current system and convert it into days

//Calculate the number of days between two dates
const diffDays = (date, otherDate) => Math.ceil(Math.abs(date - otherDate) / (1000 * 60 * 60 * 24));

Here we recommend a website, which contains all kinds of functions realized with one line of code https://1loc.dev/

Github Action scheduled task

Github Action is a virtual container service provided by GitHub. Generally speaking, it means giving you a cloud server for free. The system of the cloud server and the code running environment can be customized according to the configuration. We can only use GitHub's workflow. Interestingly, we can also set regular tasks for it, run our workflow regularly, execute the code we have written, generate pictures and upload them at one go! Totally free!

Open terminal/Command line, in git Create a new directory under the project directory and create schedule.yml configuration file

mkdir .github
mkdir .github/workflows
touch .github/workflows/schedule.yml

schedule.yml configuration

# The name of this workflow
name: CI

# When can the workflow run
  # Schedule is a scheduled task. Since the service is abroad, it needs to subtract 8 hours to be Beijing time
    - cron: '0 16 * * *'
  # This workflow is also allowed to be triggered manually in the github aciton panel

# What are the tasks in the workflow
  # This workflow contains a task named build
    # Install the latest ubuntu system
    runs-on: ubuntu-latest

    # Subtasks / steps included in this task
      # Pull the latest code
      - uses: actions/checkout@v2

      # Install the running environment of Nodejs
      - name: Setup Node.js environment
        uses: actions/setup-node@v2.4.0

   # Install the necessary system drawing library of node canvas
      - name: Setup Basically Packages
          sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev

   # Install the dependency package of our own project
      - name: Install NPM dependencies
          npm install

   # Execute our own code
      - name: Run
          node index.js "${{secrets.BILI_JCT}}" "${{secrets.SESSDATA}}" "${{secrets.DEDEUSERID}}" "${{secrets.DEDEUSERID__CKMD5}}"

The configuration is over. At 0:00 a.m. Beijing time (16:00 U.S. time) every day, the B-stop map will be automatically generated and uploaded.

Secrets in configuration XXX is the parameter carried by our code when running. In order to make it more convenient for everyone to fork this open source warehouse, I set the parameters corresponding to the user identities of the four B stations to be customizable. The parameters of such secrets can be customized and protected from disclosure in Github.

Use this project

If you just want to use this warehouse to achieve the same effect, it is very simple, because I have encapsulated it and use it immediately

Warm tip: only major members of station B can customize the header


Step 1:

fork this warehouse

Step 2:

Open station B with Chrome browser, enter your personal space, press F12 and switch to the application tab

Find the four parameters in the Cookie, then open your branch warehouse, click Settings, enter Secrets, and click New repository secret to configure the four parameters one by one

Step 3:

Manually execute the workflow once, and then it can run automatically and regularly!

Congratulations, you already have a personal space header of station B as interesting as classmate he