么是函數?剛剛考完數學沒多久的我,腦力里立馬想到的是自變量、因變量、函數值,也就是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云盤系統。
作為一個老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('登錄成功')
return True
else:
print('登錄失敗:'+msg)
return False
# 獲取用戶信息
def get_user_info():
headers = {
'Cookie':cookie
}
response = requests.session().get('http://api.bilibili.com/x/space/myinfo?jsonp=jsonp',headers=headers)
rejson = json.loads(response.text)
code = rejson['code']
msg = rejson['message']
if code == 0:
userInfo=['賬號:'+str(rejson['data']['silence']),
'硬幣:'+str(rejson['data']['coins']),
'經驗:'+str(rejson['data']['level_exp']['current_exp'])+"/"+str(rejson['data']['level_exp']['next_exp']),
'等級:'+str(rejson['data']['level']),
'昵稱:'+str(rejson['data']['name'])
]
print(userInfo[0])
print (userInfo[1])
print(userInfo[2])
print(userInfo[3])
print(userInfo[4])
return userInfo
else:
print("用戶信息獲取失?。?#34;+msg)
return "用戶信息獲取失敗:"+msg
# 直播簽到,賺銀瓜子兒
def do_sign():
headers = {
'Cookie':cookie
}
response = requests.session().get('https://api.live.bilibili.com/sign/doSign',headers=headers)
rejson = json.loads(response.text)
code = rejson['code']
msg = rejson['message']
if code == 0:
print('直播簽到成功!')
return True
else:
print("直播簽到失?。?#34;+msg)
return False
# 看BV號視頻,得觀看經驗
def watch():
aid=bv_to_av(bid)
headers = {
'Cookie':cookie
}
response = requests.session().get('http://api.bilibili.com/x/web-interface/view?aid='+str(aid),headers=headers)
rejson = json.loads(response.text)
code = rejson['code']
#print(response.text)
if code == 0:
cid = rejson['data']['cid']
duration = rejson['data']['duration']
else:
print('視頻信息解析失敗')
return False
payload = {
'aid': aid,
'cid': cid,
'jsonp': "jsonp",
'mid': uid,
'csrf': csrf,
'played_time': 0,
'pause': False,
'realtime': duration,
'dt': 7,
'play_type': 1,
'start_ts': int(time.time()),
}
response = requests.session().post('http://api.bilibili.com/x/report/web/heartbeat',data=payload,headers=headers)
rejson = json.loads(response.text)
code = rejson['code']
if code == 0:
time.sleep(5)
payload['played_time'] = duration - 1
payload['play_type'] = 0
payload['start_ts'] = int(time.time())
response = requests.session().post('http://api.bilibili.com/x/report/web/heartbeat',data=payload,headers=headers)
rejson = json.loads(response.text)
code = rejson['code']
if code == 0:
print(f"av{aid}觀看成功")
return True
print(f"av{aid}觀看失敗 {response}")
return False
def main(*args):
if login():
ui = get_user_info()
desp='直播簽到:'+str(do_sign())+'\n\n'+'觀看視頻:'+str(watch())+'\n\n'+ui[0]+'\n\n'+ui[1]+'\n\n'+ui[2]+'\n\n'+ui[3]+'\n\n'+ui[4]+'\n\n'
pushinfo('嗶哩嗶哩簽到成功',desp)
else:
pushinfo('嗶哩嗶哩簽到失敗','')
if __name__ == '__main__':
main()
2.修改函數配置
完成函數的創建后就進入了函數管理的界面。函數代碼這里就顯示了我們上傳的代碼文件,所有代碼執行的本地路徑都在/code目錄下。
如果有依賴模塊提示沒有,在下方的控制臺終端輸入命令也可以完成模塊安裝下載,所有工作目錄下的代碼修改,完成后都需要點擊部署代碼進行部署上傳。
pip install -t . requests bs4
其余需要修改一下函數的配置,點擊【函數配置】,找到【環境信息】編輯,修改【請求處理程序】,修改函數入口為<要執行的代碼文件名.執行的函數名>,我這里腳本的文件名為bilibiliSignin.py,代碼里的主函數為main,因此函數入口就為<bilibiliSignin.main>
3.完成函數功能測試
選擇【測試函數】,即可立即對函數進行觸發,點擊測試函數進行測試
完成測試后下方就會顯示日志輸出內容,方便查看結果和排錯
完成效果,定時觸發23點準時完成簽到,并由釘釘的機器人推送消息
欸嘿,大伙一起吧Serverless腳本跑起來,早日迎接B站六級會員?。?!
腳本參考Github ,by sanshuifeibing
這里我拿隔壁軟件專業(俺是網絡技術的)的一個大作業項目作為部署的案例。項目是非常簡單并且功能單一的,但是也是非常經典的前后端分離項目,由于我開發不太會,項目具體技術就不獻丑了。之前據說是有什么版權的,我就不放源代碼了hhhh
在改造之前,我相信是很多中小型公司業務的經典AllinOne結構,把業務涉及到的所有服務中間件運行在一臺服務器/虛擬機上,雖然現在看可能完完全全是實驗室環境,但是實際看到的依然有很多項目是這么做的。壞處也不用多提,部署運維難、難以進行資源的擴容、后續改造復雜、性能差沒有應用高可用技術等等。
Serverless的農產品電商平臺上云,項目比較簡單,規劃就在同一地域了。主要是將前端HTML頁面與后端Jar包運行分別由兩個單獨的Serverless函數完成運行計算。其余支撐服務上云,分別用對應的云產品實現,這里Redis服務由于我自己ECS上有運行redis服務,就不再單獨購買云數據庫Redis版了,當然推薦使用阿里云的Redis云數據庫產品。
1.Serverless服務創建
進入函數計算控制臺,選擇【服務及函數】,點擊【創建服務】
輸入創建服務的名稱與描述,開啟日志功能,點擊確定,完成服務的創建
服務創建完成后,進入【服務詳情】,找到【網絡配置】,點擊【編輯】
選擇允許訪問VPC,選擇自定義配置,選擇VPC、vSwitch、安全組,這里需要和后續其他支撐的云產品(數據庫等)保持在同一VPC下。因此需要做好云上網絡的規劃,也要看一下產品是否在地域下有沒有庫存。
2.前端頁面Serverless函數創建
完成服務創建后,點擊【創建函數】,進入函數的創建頁面
選擇【使用自定義運行時平滑遷移WebServer】,輸入函數名稱,選擇運行環境為【Nginx】,上傳前端html代碼與nginx的配置文件,選擇監聽端口為80,即為原nginx中間件的服務端口。
完成函數創建后,進入到函數詳情界面,可以在函數代碼中對代碼進行編輯修改,代碼改動后需要點擊部署代碼重新上傳。上述也提到了,這里需要將Nginx服務配置一同上傳,其中需要拷貝一份/etc/nginx/mime.types文件到當下目錄,避免mime文件類型映射錯誤。
這里放nginx關鍵配置,根據自己的業務情況修改,注意配置中端口監聽需要與函數創建監聽端口保持一致,同時網頁代碼的路徑設置為/code
http {
include mime.types; #注意引入此文件
keepalive_timeout 900;
server {
listen 80;
server_name localhost;
location / {
root /code;
index index.html index.htm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /users {
proxy_pass http://serverless.后端函數訪問地址.run;
#Nginx反代傳給后端的函數,地址在后續后端函數創建完可以拷貝
}
location /items {
proxy_pass http://serverless.后端函數訪問地址.run;
#Nginx反代傳給后端的函數,地址在后續后端函數創建完可以拷貝
}
可以在調用日志查詢相關日志
當函數觸發運行,Serverless將會根據訪問請求自動起實例,在這里可以手動登陸實例,去進行中間件服務的日志、運行環境的一些查看與排錯。
3.后端Serverless函數創建
回到函數服務界面,再次點擊【創建函數】,進入函數的創建頁面
選擇【使用自定義運行時平滑遷移WebServer】,輸入函數名稱,選擇運行環境為【Java】,上傳打包好的Jar包文件。
根據具體業務修改【啟動命令】與【監聽端口】。我這里需要監聽業務端口為8080,并且需要在運行時傳入數據庫連接的參數,這里所配置的數據庫源用戶名密碼連接地址,在后續的云數據庫RDS中會進行相關設置。
后端函數創建完成后進入函數詳情界面,其余功能與上述前端函數相同,不再復述
點擊【觸發器管理】,此處HTTP觸發器提供了公網與內網訪問地址,我們拷貝內網地址在前端中間件反代配置處填入此域名,實現訪問前端觸發后端函數
4.云數據庫RDS MySQL Serverless創建與遷移導入
原有Allinone架構中沒有做到數據庫服務的獨立與高可用,在此次云化部署,我們將選用阿里云公測中的云數據庫Serverless版本。RDS MySQL Serverless提供了CPU、內存的實時彈性能力,具有資源用量低、簡單易用、彈性靈活和價格低廉等優點,合理優化使用成本,進一步降本增效。
RDS MySQL Serverless實例創建
進入云數據庫RDS控制臺,點擊【創建實例】,開始創建實例的流程,在【基礎資源】設置界面,選擇Serverless版,其余根據實際進行選擇
Serverless RDS創建時【實例配置】需要注意網絡VPC的設置,要與Serverless服務所設定的VPC一致,實現內網數據互通。確定訂單后,等待實例創建完成即可
RDS數據庫用戶設置
完成實例創建,選擇管理實例。在左側任務欄選擇【賬號管理】,點擊【創建賬號】創建數據庫賬戶供電商平臺后端進行連接。
輸入賬戶名、密碼,選擇為普通賬戶,點擊確定完成用戶創建
RDS 業務數據庫創建
選擇左側欄中【數據庫管理】,選擇【創建數據庫】
輸入農產品電商業務所需的庫名,并且授權賬戶給前一步設置的用戶,點擊創建完成庫的設置。
RDS 服務連接地址
我們的Serverless函數中所需要連接庫的地址,在rds實例中【數據庫】連接處可以查到,不過需要提前設定白名單。
我們將內網地址進行拷貝,并且也完成了連接用戶、密碼、庫的配置,就可以配置到Serverless函數或者是后端代碼中了
RDS 業務數據庫的導入恢復
數據庫的上云關鍵是數據內容的遷移,這次部署的業務數據庫很少又很小,因此使用簡單的備份SQL腳本文件作為遷移的方式。MySQL/Mariadb的數據導出有多種方式,可以根據實際需求進行備份導出,當然大型業務庫有專用的備份遷移工具,這里不細說了。
進入DMS數據管理服務,選擇【數據庫開發】,在【數據變更】下點擊【數據導入】。
根據具體備份方式導入數據庫,我這里選擇上傳備份的sql腳本,提交申請開始導入數據
數據導入完成,數據遷移完成
5.Redis服務上云與靜態資源CDN
Redis服務上云,前文也提到了,這里Redis服務由于我自己ECS上有運行redis服務,就不再單獨購買云數據庫Redis版了,ECS也處于同一VPC之下,可以實現內網互通。當然推薦使用阿里云的Redis云數據庫產品。
靜態資源的CDN,包括css\js\圖片的加速,原有架構中已經存放在阿里的CDN服務上了,我這里就不多做改動了。
6.公網業務訪問域名配置
最后一步,用戶最終訪問的是前端Serverless函數,如同阿里云給出的提示,訪問默認的公網地址不會做任何中間件解析,而是直接下載首頁html靜態文件,因此我們需要自己配置訪問域名。
回到函數計算控制臺,選擇【域名管理】,點擊【添加自定義域名】
輸入自定的域名,配置路由,選擇對應函數的服務名稱、函數名稱、版本號LATEST(最新)
將需要解析的CNAME值,拷貝
拷貝CNAME記錄值,點擊【云解析DNS控制臺】,進入解析設置,點擊【添加記錄】
選擇記錄類型【CNAME】,輸入主機頭,填入拷貝的記錄值,確認完成添加
7.農產品電商項目Serverless上云效果
首頁,訪問效果,前端函數無誤
農產品詳情頁訪問
用戶注冊功能測試,數據庫連接與寫入無誤
RDS中數據已成功寫入
用戶登陸測試
訂單提交測試,后端函數無誤
1.基于官方模板創建應用
Serverless應用提供了大量的官方應用模板,我們可以根據給出的模板來修改自己的業務,因此熟悉模板的部署也很重要。
進入到函數計算FC的控制臺頁面,點擊【應用】,選擇【通過模板創建應用】,選擇【商城案例】
通過詳情查看部署模板的信息,以及查詢源代碼,點擊立即創建可以快速體驗Serverless應用的創建,本地部署可以通過ServerlessDev工具進行部署
2.對創建應用進行配置
點擊立即創建后,我們進行應用的初始化配置。
部署類型有兩種:1.通過第三方代碼倉庫部署,2.直接部署
兩者區別就是使用自己的倉庫代碼后續可以通過push更新項目發布,而直接部署需要手動配置。
這里就可以看到,我們的交付觸發也是以Git倉庫push提交為主,每次提交會自動觸發部署。
如是自己配置應用,需要根據業務配置s.yaml文件,參考:https://www.serverless-devs.com/fc/yaml/readme
這里我選擇Gitee倉庫進行部署,但是需要進行倉庫第三方應用的授權
點擊前往授權,跳轉到gitee的站點進行OAuth授權請求,點擊同意授權
阿里用戶在第一次使用FC函數計算時,需要對角色策略進行添加的,我這里已經使用過FC了,若提示需要添加策略,按照提示點擊添加即可。
其他高級配置,需要根據業務進行修改,這里注意地域的選定,后續的其他彈性資源都會在此地域下,我這里選擇本地杭州。
完成配置后點擊創建,代碼已經新建上傳到我的Gitee倉庫了。這里提供的s.yaml可以作為配置的參考,后續根據所部署的業務去修改yaml
3.應用部署上線
應用創建完成,首次自動進行部署,這里部署狀態可以看到正在部署
查看部署日志,如果部署出現錯誤也可以從日志信息中查詢報錯。
部署經歷了前置環境、資源同步、資源檢查、執行部署這四個步驟后,我們的電商應用就完成了部署
首次部署完成,也是最新latest的一次部署版本,可以通過部署歷史自由的進行回滾
4.訪問部署上線的電商應用
訪問測試的域名,就可以看到我們上線的litemall電商系統,進入電商應用的后臺管理
litemall電商系統是一個開源的前后端分離帶微信小程序的電商系統,具有電商平臺基礎的會員管理、商城管理、商品管理、推廣管理、系統管理、配置管理、統計報表。
litemall電商系統,需要配置最小開發環境有以下:
MySQL
JDK1.8或以上
Maven
Nodejs
5.更換業務域名訪問
同樣,當我們正常上線了FC的業務時,Serverless用的是默認訪問地址
函數計算上線提供的域名是以..http://fc.aliyuncs.com//proxy///[action?queries]為默認的,若是正常業務訪問我們必然要修改訪問的域名。
進入到函數計算FC的首頁,點擊高級功能下的域名管理,這里可以看到我們上線電商應用時的默認域名已經路由信息
我們選擇添加自定義域名
輸入域名的名稱,也就是購買備案的域名下的自定義二級域名
點擊路由配置,選擇服務名稱,這里是我們部署的電商系統litemall,選擇函數名稱與版本
拷貝公網CNAME地址,后續在DNS域名管理處添加解析
進入到域名管理下,添加一條記錄,記錄類型選擇CNAME,輸入主機記錄,將剛剛拷貝的公網CNAME地址粘到記錄值,點擊添加即可
回到函數計算FC,在最后點擊創建即可,回到主頁看到我們新綁定的域名
最后,拿手機訪問我自定義配置的公網地址
電商服務正常上線,公網地址正常訪問主頁
商品的詳情購買頁面
Serverless相對其他方案來說,也是非常容易上手并高效的技術方案。上面的部署測試,其實還有很多需要改進的地方,例如第二個農產品電商上云項目,真正可靠的云上業務還需要負載均衡、高可用多地容災、安全等其他云產品的引入,我想把案例的重點放在Serverless服務器無感化上,本人也使用過不少阿里云的技術產品,深知對底層基礎設施運維難度。
雖然這幾個月學習生活比較繁忙,但是還是對社區的各種活動非常感興趣,也想做一些更好的測試。這次的Serverless無論是對個人用戶,還是企業用戶。都是一種非常不錯的選擇,彈性資源與按需付費,更加節省資源與Money,更加優雅!
原文鏈接:http://click.aliyun.com/m/1000350415/
本文為阿里云原創內容,未經允許不得轉載。
如題,最近閑著沒事,研究出了模擬客戶端簽到的腳本。
注冊賬號,過程略。網址:https://console.cloud.tencent.com/
進入云函數控制臺的函數服務:https://console.cloud.tencent.com/scf/index?rid=1
私信小編01即可獲取大量python學習資料
python代碼:
from requests import session
from hashlib import md5
from random import random
from time import sleep
class Tieba():
def __init__(self, BDUSS, STOKEN):
self.BDUSS = BDUSS
self.STOKEN = STOKEN
self.count = [0, 0, 0] # 簽到成功, 已經簽到, 總
self.session = session()
self.session.headers.update(
{'Accept': 'text/html, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Connection': 'keep-alive',
'Host': 'tieba.baidu.com',
'Referer': 'http://tieba.baidu.com/i/i/forum',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/71.0.3578.98 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'}
)
def set_cookie(self):
self.session.cookies.update({'BDUSS': self.BDUSS, 'STOKEN': self.STOKEN})
def fetch_tbs(self):
r = self.session.get('http://tieba.baidu.com/dc/common/tbs').json()
if r['is_login'] == 1: self.tbs = r['tbs']
else: raise Exception('獲取tbs錯誤!以下為返回數據:' + str(r))
def fetch_likes(self):
self.rest = set()
self.already = set()
r = self.session.get('https://tieba.baidu.com/mo/q/newmoindex?').json()
if r['no'] == 0:
for forum in r['data']['like_forum']:
self.count[2] += 1
if forum['is_sign'] == 1:
self.already.add(forum['forum_name'])
else:
self.rest.add(forum['forum_name'])
else: raise Exception('獲取關注貼吧錯誤!以下為返回數據:' + str(r))
def sign(self, forum_name):
data = {
'kw': forum_name,
'tbs': self.tbs,
'sign': md5(f'kw={forum_name}tbs={self.tbs}tiebaclient!!!'.encode('utf8')).hexdigest()
}
r = self.session.post('http://c.tieba.baidu.com/c/c/forum/sign', data).json()
if r['error_code'] == '160002':
print(f'"{forum_name}"已簽到!')
self.count[1] += 1
return True
elif r['error_code'] == '0':
print(f'"{forum_name}"簽到成功,您是第{r["user_info"]["user_sign_rank"]}個簽到的用戶!') # Modify!
self.count[0] += 1
return True
else:
print(f'"{forum_name}"簽到失?。∫韵聻榉祷財祿簕str(r)}')
return False
def loop(self, n):
print(f'* 開始第{n}輪簽到 *')
rest = set()
self.fetch_tbs()
for forum_name in self.rest:
sleep(random() * 3)
flag = self.sign(forum_name)
if not flag: rest.add(forum_name)
self.rest = rest
def main(self, max):
self.set_cookie()
self.fetch_likes()
n = 0
if self.already:
print('* 已經簽到的貼吧 *')
for forum_name in self.already:
print(f'"{forum_name}"已簽到!')
self.count[1] += 1
while n < max and self.rest:
n += 1
self.loop(n)
print('* 本日簽到報告 *')
print(f'共{self.count[2]}個貼吧,其中簽到成功{self.count[0]}個,已經簽到{self.count[1]}個,簽到失敗{len(self.rest)}個。')
if self.rest:
print('* 簽到失敗列表 *')
for forum_name in self.rest:
print(f'"{forum_name}"簽到失敗!')
def main_handler(*args):
with open('BDUSS.txt') as f: BDUSS = f.read()
with open('STOKEN.txt') as f: STOKEN = f.read()
task = Tieba(BDUSS, STOKEN)
task.main(3)
# 不需要推送的刪除以下幾行
if task.rest:
message = f'以下為未完成列表:'
for forum in task.rest: message += '\n' + forum
data = {'text': '簽到未完全完成!', 'desp': message}
post('https://sc.ftqq.com/你的key.send', data=data)```
如圖:
回到此界面,點擊"測試"(應該會自動部署,如提示請先部署就先部署一下)
在"baidu.com/Cookie"下找到"BDUSS",復制其內容
在"passport.baidu.com/Cookie"下找到"STOKEN",復制其內容
指一算,入職已經一月有余,也參與了一兩個項目,以前做學校項目的時候,對一個功能的取舍,很多時候都取決于“那個某某應用都有,那我們也放一下吧”之類的想法;但在“每個功能對于當前產品的受眾是否有用,對產品未來的發展是否有積極意義”這一點上,卻沒有進行長足的思考。
例如:在近期的一個項目的設計中涉及到的“簽到”功能,起初我并沒有把這個功能放在心上,然而在對其進行設計的過程中,我發現,“簽到”并非像大部分人想的那樣,只是一個“放之四海而皆準”的慣用功能而已。
在互聯網的浪潮來臨以前,當人們說起“簽到”二字時,聯想起的不是每日打卡上線拿到的獎勵,更多的可能是被懲罰支配的恐懼,不論是上課點名所占據的平時分,乃至每日上班的出勤率,都和簽到的次數息息相關。
早期的簽到多以人工手寫登記的方式為主,用于記錄人員的到場情況,便于登記者對提供的內容進行調整。
傳統“簽到”的使用場景
隨著互聯網的發展,“簽到”逐漸在原先的意義基礎上,弱化了“懲罰”的概念,擴寬了簽到的時間維度(例如可以補簽),同時增加演變出了促進用戶活躍、刺激產品推廣等更多新的用途。
綜合來說,大部分的簽到功能,本質上都是一種通過獎勵(物質or心理)強化用戶行為,從而培養用戶使用習慣,最終達到推廣產品/培養忠實用戶的功能。
在討論一件事物的外化形態的時候,需要先弄明白其產生的本質原因。對于現在的App來說,“簽到”功能隨處可見。然而這樣設計的原因是什么,又能夠幫助使用者達到什么目的呢?
常見“簽到”功能的目的
目的1:促進用戶活躍度
說到“簽到”,最常見的類型大概就是獎勵型“簽到”了。這一類型,大多都會給用戶一些物質或精神獎勵,來刺激用戶重復啟動產品,培養用戶習慣,從而提升產品的活躍度。
許多產品還可以設置定時的簽到提醒,在設定好的時間,通過推送提醒用戶打卡,以防止用戶錯過各式各樣的簽到福利,舉個栗子:
京東簽到領“京豆”(左)&陰陽師簽到獎勵(右)
在京東商城中,通過連續啟動app簽到可以兌換京豆,京豆在實際消費中可直接用于支付訂單,每100京豆可抵1元現金使用。而在游戲《陰陽師》中,每日登錄搖簽都會獲得對應的獎勵,而不論是商城還是游戲,相信大家都有過“本來只想看看消息,沒想到一打開就根本停不下來”的經歷。這種時候,設計者便達到了他的目的。
目的2:增加使用,提高營收
僅僅是簡單地讓用戶打開App,并不能滿足產品設計者。一個產品存在的價值,只有在它真正被用戶使用的時候才能得到足夠的體現。于是“簽到”功能又承載了增加用戶對產品業務的使用,提高產品營收的目標。
例如:上文提到的簽到獎勵“京豆”,還有《陰陽師》簽到獲得的紅色達摩(注:快速升級式神經驗的工具),都是為了讓用戶買的更多,玩的更多,刺激用戶對產品的重復使用。
目的3:促進分享
以上提到的內容,主要是通過對“簽到”行為給予積極的反饋,使用戶在多巴胺的影響下產生預期的行為。而接下來這種簽到形式,則是利用了用戶自我實現層面的心理需求。
英語流利說的打卡頁面
這種類型的簽到往往是一個長期的、需要堅持的過程,并且可以為用戶帶來積極正向的影響。一些具有自我成長意義的簽到內容可以滿足用戶的自我實現需求(自身技能的提高)以及尊重需求(分享后得到他人的夸贊、認同),同時也可以提高產品的曝光度??粗塾嫶蚩ㄌ鞌档囊惶焯煸黾?,內心也會覺得很有成就感。
在了解了“簽到”產生的背景和原因之后,當我們要設計一個屬于自己的簽到功能的時候,需要考慮的內容有哪些呢?
“簽到”功能的設計要素
在以智能手機為媒介的互聯網時代,打開“簽到”的方式已經不僅僅局限于紙筆書寫了,針對不同類型的產品,也有分別適用的簽到方式。例如:對于單純只需要用戶登錄便可以達到促活目的的產品(例如電商、游戲產品),可以在登錄后自動彈出簽到窗口。
對于具有一定工具性,用戶需要完成任務才能體現平臺價值的(例如學習平臺、運動軟件)則可以在任務完成后跳出簽到內容,也可以將簽到放在希望引導用戶觀看的一些內容界面,增加打開次數。
大部分的“簽到”累積天數的方式不外乎累計型和連續型兩種,累計型簽到指的是:斷簽后依然計算總天數,連續型則指斷簽后需要重新開始的計算方式。對于需要用戶做比較長時間心理建設的簽到內容(例如:學習等),使用累計型的會更合適,否則用戶很容易出現“破罐破摔”,一旦斷簽就徹底放棄的情況。
一般來說,我們可以把簽到周期分為兩種:
對于簽到的獎勵內容該如何設定,這往往和產品希望培養的用戶行為直接相關,例如:希望用戶多購買東西,就可以多送優惠券,希望用戶多分享,就可以贈送一些滿足用戶虛榮心的等級積分。根據反饋內容的不同,我們還可以將簽到分成以下幾種常見類型:
(1)物質激勵型
物質激勵型包含兩種:
蝸牛睡眠挑戰計劃
這類簽到方式,具有游戲化的四個基本特性:目標、規則、反饋、自愿參與,讓用戶更容易堅持下去,甚至沉迷。但從心理學上來說,“失去”往往會帶來不良的情感體驗。
(2)精神激勵型
這類簽到,主要是利用等級、稱號、曝光率等精神獎勵刺激用戶使用,例如:Keep的運動徽章,微博話題的簽到熱度排行等等,主要利用了人們對于自我實現和尊重等處于馬斯洛需求三角上層的需求,大多數時候能帶來分享效應,但對于獲得獎勵的門檻往往要求較高(例如:一定要完成學習/運動目標才可以簽到)。
Keep運動徽章(左)& 微博超級話題簽到排行(右)
(3)體驗驅動型
這類簽到,則是將“簽到”作為產品的一種屬性,使產品擁有了每天都需要被打開的原因。例如:網易蝸牛讀書,每天免費讀書一小時,雖然沒有簽到功能,但是將其內化成了用戶每天必須打開它的理由。
蝸牛讀書,每天一小時閱讀時長免費領
這類將“簽到”基因植入產品的方法可以很好地提高整個產品的活躍度,但這種功能是建立在用戶有需求的基礎上的,如果用戶沒有閱讀的需求或傾向,免費時長再長可能也沒有吸引力。
雖然“簽到”已經成為了一個十分常見的功能,但并不意味著所有的產品都適合增加這個功能,以刺激用戶無限地喚起主頁面。
結合上文的一些分析,我們可以得出,適合設置“簽到”功能的產品大多都具有以下特點:
適合設計簽到的產品特點以及產品類型
例如以下幾類應用:
這里的閱讀類包括了小說閱讀、漫畫閱讀平臺,也包括了內容比較碎片化的新聞資訊閱讀平臺。對于內容產出者和平臺來說,用戶的活躍度是至關重要的,對于傳統內容平臺來說決定了作者的收入,對于資訊平臺而言,越多的用戶也能帶來更多的廣告投資,所以需要更多刺激用戶活躍度的設置。
金融類產品的收益曲線是每天都在變化的,即使沒有簽到獎勵,用戶大多時候每天都會進行查看,可以利用這一點給用戶一些優惠/活動,吸引用戶進行投資。
社區產品想要長期活下去,就需要提高用戶自主運營參與的程度,在獲得用戶活躍度保持社區活力的同時,還可以利用LBS技術,進行精準的運營活動地域投放。
電商類產品都希望用戶盡量多地瀏覽商品,增加下單內容,簽到和常用的大促手段有異曲同工之妙,都是為用戶創造更多的購買可能。
相比之下,以下類型的應用則不太適合使用“簽到”功能:
不適合強加“簽到”功能的應用特點
例如:殺毒軟件、天氣類軟件,這類軟件大多數時候是在后臺中完成自己的任務,對用戶的生活主要起到輔助作用的,用戶對這類產品沒有重復喚起的需求,太過強調自己的存在感反而可能招致用戶厭煩。
設想一下如果一個殺毒軟件有事沒事總是彈出提醒讓你每日簽到,恐怕會被立馬送進回收站吧…
綜上,這就是我在前輩們的思考基礎上對于“簽到”這個功能得出的一些想法,歡迎對設計感興趣的朋友們一起來討論呀~
參考內容:
蘭道鍋,在設計簽到功能的時候,我在想什么? | 人人都是產品經理. (2018). Retrieved from http://www.woshipm.com/pd/1025518.html
馬璐,如何讓簽到成為提升用戶活躍度的利器 | 人人都是產品經理(2018). Retrieved from http://www.woshipm.com/pd/992382.html
活動盒子,“打卡簽到”:APP用戶運營制勝法寶 | 人人都是產品經理. (2018). Retrieved from http://www.woshipm.com/operate/491571.html
作者:rt,公眾號:未知素設計
本文由 @未知素設計 原創發布于人人都是產品經理。未經許可,禁止轉載
題圖來自 Pexels,基于 CC0 協議
*請認真填寫需求信息,我們會在24小時內與您取得聯系。