JavaScript复原何同学B站头图细节示例详解

目录
  • 前言
  • 手把手实现它
    • 如何抓取B站的请求
    • 在nodejs里生成图片
    • 获得用户最新的投稿计算日子
    • Github Action定时任务
  • 使用本项目
    • 步骤1:
    • 步骤2:
    • 步骤3:

前言

在今年初,B站颁布了2021年的百大UP。我很喜欢其中一位UP主 @老师好我叫何同学 ,他的每一个视频都非常的有创意。

何同学也是一个极其注重细节的人,点进何同学的B站个人空间,细心的小伙伴肯定能关注到他个人空间的头图,右边显示的数字其实是何同学上次投稿距今的时间,这个数字每天都会变。

这也太细节了吧~

我并不知道何同学具体是如何实现的,但大帅作为一个热爱编程的程序,思路很快就在我脑海里浮现出来了。花了一天的时间敲代码和Debug,我已经完全实现了和何同学一样的效果,并且无需服务器无需打开电脑,头图每天也会自动更新。

代码已在github开源,如果你只是想使用它,并不想知道技术细节,请直接跳到最后看使用教学。

接下来我会手把手教你一步步去实现它,如果你想跟我一起用编程玩转创意,也请点赞收藏分享支持一下吧。

本文配套视频:www.bilibili.com/video/BV1bS…

手把手实现它

好的,接下来你会学习到

  • 如何抓取B站的请求
  • 在nodejs里生成图片
  • 获得用户最新的投稿计算日子
  • GithubAction定时更新头图

如何抓取B站的请求

自动的前提是手动,所以我们要先了解如何手动操作才可以更换个人空间头图(此功能需要B站的大会员),打开B站你的个人空间,点击头图右上角的这个区域更换皮肤

在网页底部会弹出更换头图的操作面板,上传任意图片作为头图的功能只有大会员才有。

接下来常规操作,我们按下F12打开调试面板,切换到network标签,此时我们上传一张图片,就可以抓取到这个上传头图的接口了

https://space.bilibili.com/ajax/topphoto/uploadTopPhotov2

点击鼠标右键,选择Copy -> Copy as Node.js fetch

打开VSCode粘贴

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

//如果你的环境支持ESModule,那么使用importimport fetch from 'node-fetch';
//如果是用require导入
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));

现在你已经可以把刚才的上传图片的操作通过代码完成了,那么这一堆参数里,我们需要注意哪些呢?

  • cookie

用户身份校验的参数,我们主要会用到bili_jctSESSDATADedeUserIDDedeUserID__ckMd5

  • body

topphoto为图片base64编码的数据,csrf就是bili_jct

如果是自己用,那么你只需要生成图片并转为base64编码后通过topphoto参数提交给B站接口就可以了

在nodejs里生成图片

在网页里生成图片大概率你知道要用canvas,比如我在码上掘金里写的这个demo。代码片段

其实在node环境里生成图片,也有一个canvas的库可以用。

npm install canvas

这个库在不同的系统下还需要安装不同的底层绘制库。

# 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`

因为我不用windows,所以windows的小伙伴自己去看官方的安装说明吧github.com/Automattic/…

使用这个库绘图的API设计和网页canvas基本相同。

//导入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();

有了背景图,现在我们加入文字

//注册字体
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中也可以实现

//设置接下来倾斜的原点为文字的左上角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个字符的图片头信息,所以我们还要截取一下

canvas.toDataURL("image/png").substring(22);

当然,你现在并不能确定咱们生成的图片是否正确,所以你也可以将图片保存成本地文件先看看是不是对了

fs.writeFileSync("test.png",canvas.toBuffer());

获得用户最新的投稿计算日子

通过接口https://api.bilibili.com/x/space/arc/search可以抓取指定用户的投稿视频

//pn为页数,ps为每页条数,order=pubdate代表按发布时间返回数据
fetch("https://api.bilibili.com/x/space/arc/search?mid="+DEDEUSERID+"&pn=1&ps=1&order=pubdate&jsonp=jsonp");

在每条视频的信息里,created属性代表了发布时间(单位:秒),我们需要计算一下这个时间和当前系统的时间差并转换为天为单位

//计算两个日期相差的天数
const diffDays = (date, otherDate) => Math.ceil(Math.abs(date - otherDate) / (1000 * 60 * 60 * 24));

这里推荐给大家一个网站,里面收录了各种用一行代码实现的功能 1loc.dev/

Github Action定时任务

Github ActionGithub提供的虚拟容器服务,通俗点说就是免费给你一台云服务器,这个云服务器的系统是什么,具备哪些代码运行环境通通都可以根据配置自定义。我们通过github的工作流workflow来使用它,有趣的是,我们还可以给它设置定时任务来定期运行我们的工作流,执行我们写好的代码,生成图片上传一气呵成!完全免费!

打开终端/命令行,在git项目目录下新建目录并创建schedule.yml配置文件

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

schedule.yml配置

# 这个工作流的名称
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/setup-node@v2.4.0

       # 安装好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站大会员可以自定义头图

https://github.com/ezshine/auto-bilibili-topphoto

步骤1:

fork本仓库

步骤2:

Chrome浏览器打开B站,进入自己的个人空间,按下F12,切换到application标签

Cookie中找到这四个参数,然后打开自己分支仓库,点击Settings,进入Secrets,点击New repository secret将四个参数一一配置好

步骤3:

手动执行一次工作流,以后就可以自动定时运行了!

恭喜,现在你已经拥有了和何同学一样有趣的全自动B站个人空间头图。

以上就是JavaScript复原何同学B站头图细节示例详解的详细内容,更多关于JavaScript复原头图的资料请关注我们其它相关文章!

(0)

相关推荐

  • Js实现当前点击a标签变色突出显示其他a标签回复原色

    当一个页面有多个a标签,且点击后会跳转至当前页面,如何实现被点击标签变色突出显示,其他标签回复原色呢? 利用JS可实现: 假设当前页面是"1.aspx" 1. 给a标签ID设值: 复制代码 代码如下: <a href="1.aspx?id=1" id="1" target="_parent">""</a> <a href="1.aspx?id=2" id=&

  • 带左右箭头图片轮播的JS代码

    轮播图实现效果见下图,图片能自己轮播,点击左右按钮进行翻页轮播,鼠标悬停图片或者标题上,停止轮播: 效果图为: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/19

  • 用js实现简单轮播图

    本文实例为大家分享了js实现简单轮播图的具体代码,供大家参考,具体内容如下 1.实现功能: 2.实现思路: (1)鼠标放到图片上,显示箭头,用display来做. (2)动态生成小圆圈. (3)小圆圈的排他思想 (4)点击小圆圈滚动图片 设置自定义属性:this.setAttribute(name, value); 获取自定义属性:this.getAttribute(name,value); (5)点击右按钮,滚动一张图片(学习无缝滚动原理) (6)克隆第一张图片放到图片最后面 li.clone

  • 简单的实现点击箭头图片切换的js代码

    步骤如下: (1) 准备图片(左右箭头,以及一些示例图片) (2) JS(jquery)的代码如下: 复制代码 代码如下: <script type="text/javascript" src="JS/jquery-1.4.4.js"></script> <script type="text/javascript"> var picPath = new Array(); picPath.push("I

  • JavaScript复原何同学B站头图细节示例详解

    目录 前言 手把手实现它 如何抓取B站的请求 在nodejs里生成图片 获得用户最新的投稿计算日子 Github Action定时任务 使用本项目 步骤1: 步骤2: 步骤3: 前言 在今年初,B站颁布了2021年的百大UP.我很喜欢其中一位UP主 @老师好我叫何同学 ,他的每一个视频都非常的有创意. 何同学也是一个极其注重细节的人,点进何同学的B站个人空间,细心的小伙伴肯定能关注到他个人空间的头图,右边显示的数字其实是何同学上次投稿距今的时间,这个数字每天都会变. 这也太细节了吧~ 我并不知道

  • JavaScript进阶之前端文件上传和下载示例详解

    目录 文件下载 1.通过a标签点击直接下载 2.open或location.href 3.Blob和Base64 文件上传 文件上传思路 File文件 上传单个文件-客户端 上传文件-服务端 多文件上传-客户端 大文件上传-客户端 大文件上传-服务端 文件下载 1.通过a标签点击直接下载 <a href="https:xxx.xlsx" rel="external nofollow" download="test">下载文件</

  • C++中#include头文件的示例详解

    fstream是C++ STL中对文件操作的合集,包含了常用的所有文件操作.在C++中,所有的文件操作,都是以流(stream)的方式进行的,fstream也就是文件流file stream. 最常用的两种操作为: 1.插入器(<<) 向流输出数据.比如说打开了一个文件流fout,那么调用fout<<"Write to file"<<endl;就表示把字符串"Write to file"写入文件并换行. 2.析取器(>>

  • Python绘制惊艳的桑基图的示例详解

    目录 桑基图简介 什么是桑基图? 如何绘制桑基图? 桑基图绘图基础 调整节点位置和图表宽度 添加有意义的悬停标签 桑基图简介 很多时候,我们需要一种必须可视化数据如何在实体之间流动的情况.例如,以居民如何从一个国家迁移到另一个国家为例.这里演示了有多少居民从英格兰迁移到北爱尔兰.苏格兰和威尔士. 从这个 桑基图 (Sankey)可视化中可以明显看出,从England迁移到Wales的居民多于从Scotland或Northern Ireland迁移的居民. 什么是桑基图? 桑基图通常描绘 从一个实

  • R语言绘制维恩图ggvenn示例详解

    目录 引言 1.安装 2.基础用法 3.图形美化 4.提取交集部分并输出 引言 韦恩图,Venn diagram,常用图的一种,用来展示集合之间的特异性和共同性.现在有很多在线的网站都可以绘制,但是R来画也方便,其中ggvenn是基于ggplot2的专门绘制韦恩图的R包. 官方网站:https://github.com/yanlinlin82/ggvenn 1.安装 ggvenn在CRAN上,直接用Install.packages就可以完成安装: > install.packages("g

  • 使用vue实现玉兔迎春图高亮示例详解

    目录 正文 一.明确需求 二.进行分析 2.1 思路 2.2 ocr 2.3 应用 三.使用 后记 正文 兔年来临,老板意气风发的说:我们的系统登录页要换做玉兔迎春的背景页,而且用户ctrl+f搜索[玉兔迎春]关键字时,图片要高亮. 新的一年,祝大家身体健康.Bug-- 一.明确需求 将系统的登录页面背景换做如上图[玉兔迎春]. 而且,用户可以通过搜索关键字[玉兔迎春]让背景图的文字进行高亮. 下面我们进行分析一下. 二.进行分析 接到该需求的时候,心里感觉‘’你在逗我‘’这样子的. 于是,老板

  • Java数据结构中图的进阶详解

    目录 有向图 有向图API设计 有向图的实现 拓扑排序 拓扑排序图解 检测有向图中的环 检测有向环的API设计 检测有向环实现 代码 基于深度优先的顶点排序 顶点排序API设计 顶点排序实现 代码: 有向图 有向图的定义及相关术语 定义∶ 有向图是一副具有方向性的图,是由一组顶点和一组有方向的边组成的,每条方向的边都连着 一对有序的顶点. 出度∶ 由某个顶点指出的边的个数称为该顶点的出度. 入度: 指向某个顶点的边的个数称为该顶点的入度. 有向路径︰ 由一系列顶点组成,对于其中的每个顶点都存在一

  • JavaScript稀疏数组与孔hole示例详解

    目录 稀疏数组是什么 JavaScript数组天生就是稀疏数组 JavaScript数组稀疏特性带来的“怪异现象” slice会复制孔 forEach.every会跳过孔(不对孔调用回调函数) map不对孔调用回调函数,但是孔会保留 filter不对孔调用回调函数,但是孔会被过滤掉 join会将孔转化为一个空字符串进行拼接,与undefined一样 初始化无孔数组的方法 Array.apply(null, Array(n))的原理 稀疏数组是什么 在绝大多数JavaScript的实现中,数组是稀

  • JavaScript函数封装的示例详解

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,

  • EasyX绘制透明背景图的方法详解

    目录 三元光栅操作 优化方案 三元光栅操作 根据在网上的搜索总结得到两种方案,最常见的绘制带有透明背景的图像的方案都是采用如下的源图像和掩码图像叠加来消去边缘部分: IMAGE img[2]; loadimage(&img[0], "sun1.png", 100, 100); // 掩码图像 loadimage(&img[1], "sun0.png", 100, 100); // 源图像 putimage(0, 0, &img[0], NOT

随机推荐