【Serverless实战】B站每日自动签到&&传统单节点网站的Serverless上云
什么是函数?刚刚考完数学没多久的我,脑力里立马想到的是自变量、因变量、函数值,也就是y=f(x)。当然,在计算机里,函数function往往指的是一段被定义好的代码程序,我们可以通过传参调用这个定义好的函数,实现我们所需要的功能。那么,今天的函数计算FC又是什么?
云计算时代的当下,容器化技术与各种工具发展的DevOps,已经把开发与运维的工作进行了新的统筹,开发人员在完成代码的编写后,无需考虑环境,直接提交到各种流水线就可以完成测试、开发、部署,项目构建微服务,由容器完成环境的封装。但是往往我们最终还是需要投入精力到业务上线的集群,是私有云环境还是公有云?是裸金属服务器还是云实例ECS?是自购还是租用?
当然,DevOps的落地,服务器\集群的运维,这些都是需要投入大量的资源与精力,DevOps是一条捷径,但不是唯一的出路。因此函数计算FC的出现,带来了无服务Serverless的架构,让开发者在开发和部署的时候,不在有部署服务复杂的感觉,对服务器的无感化,可以使开发者真正的关注在自己的代码上。阿里云Serverless函数式极简编程可专注于业务创新,无采购和部署成本、提供监控报警等完备的可观测能力。函数计算是事件驱动的全托管计算服务,真正的无需去考虑服务器的运维管理,只需要完成开发的代码进行上传,函数计算会通过角色策略去规划计算资源,弹性的方式执行函数,最后高效的执行部署。优雅!
Serverless 将会有那些适用场景?是个人?还是生产?那么这次我将部署两种不同方向的应用对Serverless进行测评
一、通知系统与Webhook,Trigger触发与Chat机器人。许多系统中涉及到的push类功能,例如邮件、短信、Webhook。当然Webhook的能力不只是信息通知,不过这里所指的通知功能必然是需要基础设施也就是服务器来支撑运行,如果将这些功能直接由Serverless来操作,我们便无需支付运维一台服务器,节省了大量的工作与费用。同样,我们可以利用Serverless事件驱动模型实现定时自动触发任务,自动签到自动发送。
二、其次当然是Web类的应用。基于各类Web框架的应用部署,构建基于Java、Python、PHP等语言的站点,Serverless很容易实现如wordpress这样的博客应用的上线。配合其他云产品,Codeup、OSS、RDS等,更能实现高可用高性能的Web应用,如官方提供的Kod云盘系统。
一、使用Serverless实现B站每日登陆签到
作为一个老b站用户,b站等级无疑是妥妥的"名片",当然我早已是六级大佬的一员了。b站升级所需的经验值是关键,登陆、投币、观看都会积累经验。为了可以快速升级,这次我将使用阿里云Serverless,实现每日b站的登陆经验Get,观看视频经验Get,观看直播银瓜子Get(白嫖的直播送礼道具),并且配合钉钉机器人,实现Webhook的消息推送。
1.创建Serverless服务及函数
进入函数计算FC控制台,选择【服务及函数】,点击【创建服务】
在【创建服务】的页面中,输入服务名称,并选择启用日志功能,日志更能可以帮助我们更好的排查错误
这里我当然需要标注服务的功能,即实现bilibili的日常登陆签到。
进入【创建函数】页面,选择【使用标准Runtime从零创建】
配置函数名称,选择运行环境为Python3,并且选择从文件夹上传代码。
注意,这里如果有依赖包需要提前下载到代码包下,我这里需要用到requests包 ,在本地需要执行 pip install -t . <模块名称>。不过后续也可以在控制台处执行下载命令
这里的Python功能实现的脚本是定时触发类的,因此我们选择请求处理程序类型为【处理事件请求】
下方配置触发器,选择定时触发器,输入名称,选择【指定时间】,我这里选择的是每日的23点进行脚本的运行
Python脚本内容
# -*- coding: utf8 -*-
import requests
import json
import time
import re
import sys
import codecs
from bs4 import BeautifulSoup
from json.decoder import JSONDecodeError
# B站登陆Cookie
cookie = ""
# Webhook地址
webhook = "https://oapi.dingtalk.com/robot/send?access_token=xxxx"
# 自动观看的BV号,杰伦新专-最伟大的作品
bid = 'BV1ua411p7iA'
uid=re.match('(?<=DedeUserID=).*?(?=;)',cookie)
sid=re.match('(?<=sid=).*?(?=;)',cookie)
csrf=re.match('(?<=bili_jct=).*',cookie)
# 部分编码问题
sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
# bv转为av
def bv_to_av(bv):
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
}
r = requests.get('https://api.bilibili.com/x/web-interface/view', {'bvid': bv}, headers=headers)
response = decode_json(r)
try:
return str(response['data']['aid'])
except (KeyError, TypeError):
return '883409884'
# json解析
def decode_json(r):
try:
response = r.json()
except JSONDecodeError:
return -1
else:
return response
# 自定义钉钉机器人推送
def pushinfo(info,specific):
# 定义推送内容,格式参考https://open.dingtalk.com/document/group/message-types-and-data-format
# 注意机器人的关键词
data = {
"msgtype": "text",
"text": {
"title":"Taoreset",
"content": "【Taoreset-Serverless推送】\n"+info+specific
}
}
headers = {'content-type': 'application/json'} # 请求头
r = requests.post(webhook, headers=headers, data=json.dumps(data))
r.encoding = 'utf-8'
print (r.text)
# 阿b登录,得登陆经验
def login():
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
'Cookie':cookie
}
response = requests.session().get('http://api.bilibili.com/x/space/myinfo',headers=headers)
rejson = json.loads(response.text)
code = rejson['code']
msg = rejson['message']
if code == 0:
print('登录成功')