Python + GitHub Actions 实现 CSDN 自动签到与抽奖(非 selenium 版本)
文章目錄
- 【1x00】技術棧
- 【2x00】代碼實現簽到與抽獎
- 【3x00】簽到結果通知
- 【03x01】Server 醬
- 【03x02】企業微信
- 【03x03】釘釘
- 【4x00】自動簽到
- 【5x00】完整代碼
- 【6x00】如何使用
- 【06x01】方法一:直接 Fork 代碼(推薦)
- 【06x01】方法二:自己上傳代碼
-
本文旨在交流 Python 編程技術,若有侵犯 CSDN 利益,請聯系我刪除文章(直接給我刪了也行😁)。
-
其他爬蟲實戰代碼合集(持續更新):https://github.com/TRHX/Python3-Spider-Practice
-
爬蟲實戰專欄(持續更新):https://itrhx.blog.csdn.net/article/category/9351278
>>> 如果你想直接使用,不想看廢話,請直接看【6x00】如何使用部分<<<
【1x00】技術棧
- 語言:Python
- 功能:簽到、抽獎(可選)
- 自動簽到:GitHub Actions
- 簽到結果通知:Server 醬(可選)、企業微信(可選)、釘釘(可選)
【2x00】代碼實現簽到與抽獎
對簽到和抽獎的過程抓包分析,可以揪出以下兩個鏈接:
- 簽到:https://me.csdn.net/api/LuckyDraw_v2/signIn
- 抽獎:https://me.csdn.net/api/LuckyDraw_v2/goodLuck
兩者的請求方式都是 post,且兩者的 Request headers 和 Request Payload 都一樣。重要參數有三個:cookie、username、uuid,cookie 參數暫時沒辦法解決,只能自己登陸后復制過來,username 是你的 id,可以在【個人中心】—【個人資料】—【基本信息】—【用戶 ID】查看,uuid 就是 cookie 里面第一個參數 uuid_tt_dd 的值。用 Python 實現基本的簽到與抽獎功能如下(此代碼可直接運行,需要將 CSDN_ID 和 COOKIE 換成你的,COOKIE 可以在已經登錄的任意頁面 F12 獲取):
import requests import jsonCSDN_ID = '' # 你的 CSDN ID COOKIE = '' # 你的 cookie IF_LUCK_DRAW = True # 是否開啟抽獎class CSDN:def __init__(self):self.UUID = COOKIE.split(';', 1)[0].split('=', 1)[1]self.USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36'self.SIGN_IN_URL = 'https://me.csdn.net/api/LuckyDraw_v2/signIn'self.LUCKY_DRAW_URL = 'https://me.csdn.net/api/LuckyDraw_v2/goodLuck'self.DRAW_TIMES = 0 # 可抽獎次數self.HEADERS = {'accept': 'application/json, text/plain, */*','accept-encoding': 'gzip, deflate, br','accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7','content-length': '243','content-type': 'application/json;charset=UTF-8','cookie': COOKIE,'origin': 'https://i.csdn.net','referer': 'https://i.csdn.net/','sec-fetch-dest': 'empty','sec-fetch-mode': 'cors','sec-fetch-site': 'same-site','user-agent': self.USER_AGENT}self.DATA = {'ip': '','platform': 'pc-my','product': 'pc','user_agent': self.USER_AGENT,'username': CSDN_ID,'uuid': self.UUID}def csdn_sign_in(self):response = requests.post(url=self.SIGN_IN_URL, headers=self.HEADERS, data=self.DATA)result = json.loads(response.text)# print(result)if result['code'] == 200:if not result['data']['isSigned'] and result['data']['signed']:keep_count = result['data']['keepCount']total_count = result['data']['totalCount']total_signed_count = result['data']['totalSignedCount']# self.STAR = result['data']['star']self.DRAW_TIMES = result['data']['drawTimes']print('簽到成功!你已連續簽到 {} 天,累計簽到 {} 天,當前已有 {} 人簽到。'.format(keep_count, total_count, total_signed_count))elif result['data']['isSigned']:print('你今天已經簽到過了喲!')else:print('簽到失敗!')elif result['code'] == 400102:print('簽到失敗!{} 用戶不存在或者 cookie 錯誤!請檢查 CSDN ID 或嘗試重置 cookie!'.format(CSDN_ID))else:print('簽到失敗!')def csdn_luck_draw(self):if self.DRAW_TIMES != 0:response = requests.post(url=self.LUCKY_DRAW_URL, headers=self.HEADERS, data=self.DATA)result = json.loads(response.text)# print(result)if result['code'] == 200:if result['data']['can_draw']:prize_title = result['data']['prize_title']print('抽獎成功!恭喜你獲得{}'.format(prize_title))elif not result['data']['can_draw']:print('抽獎機會已經用完了喲!')else:print('抽獎失敗!')elif result['code'] == 400102:print('抽獎失敗!{} 用戶不存在或者 cookie 錯誤!請檢查 CSDN ID 或嘗試重置 cookie!'.format(CSDN_ID))else:print('抽獎失敗!')def run():c = CSDN()c.csdn_sign_in()if IF_LUCK_DRAW:c.csdn_luck_draw()if __name__ == '__main__':run()【3x00】簽到結果通知
【03x01】Server 醬
Server 醬首頁:sc.ftqq.com
什么是 Server 醬?簡單來說,登錄 Server 醬后,會分配給你一個 SCKEY,通過向專門的 URL 發送 get 或者 post 請求,你的微信就會收到對應的消息,對于不使用企業微信和釘釘的用戶來說,這種方法是最方便的。目前有標準版和 Turbo 版,據說標準版會下線,目前還能使用,所以暫時使用的是標準版。若被棄用,我會第一時間更新。實現效果:
【03x02】企業微信
如果你是一個企業微信群的群主,那么可以在群名右鍵添加一個機器人,添加成功后會給你一個機器人的 URL 地址,向這個 URL 發送 post 請求就可以在群里看到對應的消息,支持 markdown、text、圖片等多種格式,具體可以查看機器人配置說明。
【03x03】釘釘
和企業微信類似,如果你是一個釘釘群的群主,依次右鍵【群設置】—【群智能助手】—【添加機器人】,選擇自定義(通過webhook接入自定義訪問)機器人,安全設置里面選擇【加簽】,添加完成后你會得到一個機器人的 Webhook URL 和一個加簽的密鑰,之后使用特定的算法將一些參數和 URL 組成新的 URL,再向這個 URL 發送 post 請求就可以在群里收到消息了,具體使用方法參見官方文檔:https://developers.dingtalk.com/document/app/custom-robot-access
【4x00】自動簽到
這里自動簽到使用的是 GitHub Actions,這是 GitHub 提出的一項持續集成服務,它提供了一個高效易用的 CI/CD 工作流,能夠幫助我們自動構建、測試和部署我們的代碼,簡單來說,對于我們的自動簽到程序,它能夠每天定時運行一遍,以達到每天簽到的目的,如果有 cookie,密鑰之類的參數,可以在倉庫的 【Settings】—【Secrets】里面添加。定時任務和運行環境等其他參數統一在一個 .yml 文件中配置。
GitHub Actions 官方文檔:https://docs.github.com/cn/actions
【5x00】完整代碼
CSDN 簽到抽獎主程序代碼 CSDN.py :
注:代碼不能直接運行,這是放到 GitHub Actions 上執行的代碼,使用方法見【6x00】,如果要本地運行,則需要將配置項目 1 2 3 中 os.environ["xxxxx"] 換成各自對應的值!
# ==================================== # --*-- coding: utf-8 --*-- # @Time : 2021-05-29 # @Author : TRHX ? 鮑勃 # @Blog : www.itrhx.com # @CSDN : itrhx.blog.csdn.net # @FileName: CSDN.py # @Software: PyCharm # ====================================import requests import json import os import time import hmac import hashlib import base64 import urllib.parse# ============== 1.CSDN 個人信息 ============== # CSDN_ID = os.environ["CSDN_ID"] # 必填!CSDN 的 ID COOKIE = os.environ["COOKIE"] # 必填!已登錄的 cookie# ============== 2.功能開關配置項 ============== # # 填 on 則開啟,開啟的同時也需要配置3中的選項,不填或填其他則關閉 IF_LUCK_DRAW = os.environ["IF_LUCK_DRAW"] # 選填!是否開啟抽獎 IF_SEVER = os.environ["IF_SEVER"] # 選填!是否開啟 server 醬通知 IF_WECHAT = os.environ["IF_WECHAT"] # 選填!是否開啟企業微信通知 IF_DING = os.environ["IF_DING"] # 選填!是否開啟釘釘通知# ============== 3.消息通知配置項 ============== # SEVER_SCKEY = os.environ["SEVER_SCKEY"] # 選填!server 醬的 SCKEY WECHAT_URL = os.environ["WECHAT_URL"] # 選填!企業微信機器人地址 DING_URL = os.environ["DING_URL"] # 選填!釘釘機器人地址 DING_SECRET = os.environ["DING_SECRET"] # 選填!釘釘機器人加簽 SECRET# ============== 4.準備發送的消息 ============== # TEXT = '' DESP = ''class CSDN:def __init__(self):self.DRAW_TIMES = 0 # 可抽獎次數self.UUID = COOKIE.split(';', 1)[0].split('=', 1)[1]self.USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36'self.SIGN_IN_URL = 'https://me.csdn.net/api/LuckyDraw_v2/signIn'self.LUCKY_DRAW_URL = 'https://me.csdn.net/api/LuckyDraw_v2/goodLuck'self.HEADERS = {'accept': 'application/json, text/plain, */*','accept-encoding': 'gzip, deflate, br','accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7','content-length': '243','content-type': 'application/json;charset=UTF-8','cookie': COOKIE,'origin': 'https://i.csdn.net','referer': 'https://i.csdn.net/','sec-fetch-dest': 'empty','sec-fetch-mode': 'cors','sec-fetch-site': 'same-site','user-agent': self.USER_AGENT}self.DATA = {'ip': '','platform': 'pc-my','product': 'pc','user_agent': self.USER_AGENT,'username': CSDN_ID,'uuid': self.UUID}def csdn_sign_in(self):global TEXT, DESPresponse = requests.post(url=self.SIGN_IN_URL, headers=self.HEADERS, data=self.DATA)result = json.loads(response.text)# print(result)if result['code'] == 200:if not result['data']['isSigned'] and result['data']['signed']:keep_count = result['data']['keepCount']total_count = result['data']['totalCount']total_signed_count = result['data']['totalSignedCount']# self.STAR = result['data']['star']self.DRAW_TIMES = result['data']['drawTimes']TEXT = 'CSDN 簽到成功!'DESP = 'CSDN 簽到成功!你已連續簽到 {} 天,累計簽到 {} 天,當前已有 {} 人簽到。'.format(keep_count, total_count, total_signed_count)print('簽到成功!你已連續簽到 {} 天,累計簽到 {} 天,當前已有 {} 人簽到。'.format(keep_count, total_count, total_signed_count))elif result['data']['isSigned']:TEXT = 'CSDN 簽到失敗!'DESP = 'CSDN 簽到失敗!你今天已經簽到過了喲!'print('你今天已經簽到過了喲!')else:TEXT = 'CSDN 簽到失敗!'print('簽到失敗!')elif result['code'] == 400102:TEXT = 'CSDN 簽到失敗!'DESP = 'CSDN 簽到失敗!{} 用戶不存在或者 cookie 錯誤!請檢查 CSDN ID 或嘗試重置 cookie!'.format(CSDN_ID)print('簽到失敗!{} 用戶不存在或者 cookie 錯誤!請檢查 CSDN ID 或嘗試重置 cookie!'.format(CSDN_ID))else:TEXT = 'CSDN 簽到失敗!'print('簽到失敗!')def csdn_luck_draw(self):if self.DRAW_TIMES != 0:global TEXT, DESPresponse = requests.post(url=self.LUCKY_DRAW_URL, headers=self.HEADERS, data=self.DATA)result = json.loads(response.text)print(result)if result['code'] == 200:if result['data']['can_draw']:prize_title = result['data']['prize_title']TEXT += 'CSDN 抽獎成功!'DESP += '抽獎成功!恭喜你獲得{}'.format(prize_title)print('抽獎成功!恭喜你獲得{}'.format(prize_title))elif not result['data']['can_draw']:TEXT += 'CSDN 抽獎失敗!'DESP += 'CSDN 抽獎失敗!抽獎機會已經用完了喲!'print('抽獎機會已經用完了喲!')else:TEXT += 'CSDN 抽獎失敗!'print('抽獎失敗!')elif result['code'] == 400102:TEXT = 'CSDN 抽獎失敗!'DESP = 'CSDN 抽獎失敗!{} 用戶不存在或者 cookie 錯誤!請檢查 CSDN ID 或嘗試重置 cookie!'.format(CSDN_ID)print('抽獎失敗!{} 用戶不存在或者 cookie 錯誤!請檢查 CSDN ID 或嘗試重置 cookie!'.format(CSDN_ID))else:TEXT += 'CSDN 抽獎失敗!'print('抽獎失敗!')class Notice:@staticmethoddef sever():requests.get('https://sc.ftqq.com/{}.send?text={}&desp={}'.format(SEVER_SCKEY, TEXT, DESP))@staticmethoddef wechat():data = {'msgtype': 'text','text': {'content': DESP}}headers = {'content-type': 'application/json'}requests.post(url=WECHAT_URL, headers=headers, data=json.dumps(data))@staticmethoddef ding():timestamp = str(round(time.time() * 1000))secret = DING_SECRETsecret_enc = secret.encode('utf-8')string_to_sign = '{}\n{}'.format(timestamp, secret)string_to_sign_enc = string_to_sign.encode('utf-8')hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))headers = {'Content-Type': 'application/json'}complete_url = DING_URL + '×tamp=' + timestamp + "&sign=" + signdata = {"text": {"content": DESP},"msgtype": "text"}requests.post(url=complete_url, data=json.dumps(data), headers=headers)def run():c = CSDN()n = Notice()c.csdn_sign_in()if IF_LUCK_DRAW == 'on':c.csdn_luck_draw()if IF_SEVER == 'on':n.sever()if IF_WECHAT == 'on':n.wechat()if IF_DING == 'on':n.ding()if __name__ == '__main__':run()GitHub Actions 工作流配置文件 csdn-sign-in.yml:
# This workflow will install Python dependencies, run tests and lint with a single version of Python # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actionsname: CSDN Sign Inon:push:branches: [ main ]pull_request:branches: [ main ]schedule:- cron: 0 16 * * *jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v2- name: Set up Python 3.9uses: actions/setup-python@v2with:python-version: 3.9- name: Install dependenciesrun: |python -m pip install --upgrade pippip install requestsif [ -f requirements.txt ]; then pip install -r requirements.txt; fi- name: CSDNrun: |python3 CSDN.py env: CSDN_ID: ${{ secrets.CSDN_ID }}COOKIE: ${{ secrets.COOKIE }}IF_LUCK_DRAW: ${{ secrets.IF_LUCK_DRAW }}IF_SEVER: ${{ secrets.IF_SEVER }}IF_WECHAT: ${{ secrets.IF_WECHAT }}IF_DING: ${{ secrets.IF_DING }}SEVER_SCKEY: ${{ secrets.SEVER_SCKEY }}WECHAT_URL: ${{ secrets.WECHAT_URL }}DING_URL: ${{ secrets.DING_URL }}DING_SECRET: ${{ secrets.DING_SECRET }}所需環境 requirements.txt:
requests【6x00】如何使用
【06x01】方法一:直接 Fork 代碼(推薦)
代碼地址:https://github.com/TRHX/CSDNSignIn
點擊右上角【Fork】代碼到你的賬戶,然后點擊【Settings】—【Secret】—【New repository secret】,依次填入以下 Name 以及對應的 Value:
| CSDN_ID | 是 | CSDN 的 ID | qq_36759224 |
| COOKIE | 是 | 已登錄的 cookie | uuid_tt_dd=10_287647… |
| IF_LUCK_DRAW | 否 | 是否開啟抽獎 | on |
| IF_SEVER | 否 | 是否開啟 server 醬通知 | on |
| IF_WECHAT | 否 | 是否開啟企業微信通知 | on |
| IF_DING | 否 | 是否開啟釘釘通知 | on |
| SEVER_SCKEY | 取決于 IF_SEVER | server 醬的 SCKEY | SCU165692T… |
| WECHAT_URL | 取決于 IF_WECHAT | 企業微信機器人地址 | https://qyapi.weixin.qq.com/cgi-bin/webhook/… |
| DING_URL | 取決于 IF_DING | 釘釘機器人地址 | https://oapi.dingtalk.com/robot/send… |
| DING_SECRET | 取決于 IF_DING | 釘釘機器人加簽 SECRET | SEC1cb948ba… |
舉例:我需要開啟抽獎和 server 醬通知,則需要填的有:
| CSDN_ID | qq_36759224 |
| COOKIE | uuid_tt_dd=10_287647… |
| IF_LUCK_DRAW | on |
| IF_SEVER | on |
| SEVER_SCKEY | SCU165692T… |
如果你需要更改每天簽到的時間,則需要更改 .github/workflows/csdn-sign-in.yml 文件里面 cron: 0 16 * * * 的值,這里使用的是 Linux crontab 定時任務命令,0 16 * * * 表示每天凌晨運行一次,注意這里使用的是 UTC 國際標準時間,與北京時間相差 8 個小時,所以 UTC 時間 16 點也就是北京時間的 24 點。
注意:
-
cookie 的值需要你登錄后 F12 查看復制過來,cookie 的有效期是多久暫時不得而知,等下次失效了我再回來告訴你們有效期是多久,如果我沒說,那就代表一直沒失效!😁
-
經過測試,cookie 的有效期在 45 天左右,失效后需要重新復制一個新 cookie 過來!
-
如果你開啟了自動抽獎,程序會識別你當前還有多少次抽獎次數,如果抽獎次數為0,則仍然不執行抽獎任務!
【06x01】方法二:自己上傳代碼
將【5x00】完整代碼中的 CSDN.py 以及所需環境 requirements.txt 上傳到自己的 GitHub 倉庫,點擊倉庫的 【Actions】,選擇【Python application】,點擊【Set up this workflow】創建工作流,之后會出來一個 python-app.yml,參考【5x00】完整代碼中的 csdn-sign-in.yml,添加定時任務和參數配置,編輯完成后點擊【Start commit】提交。
當然也可以直接在本地編寫好配置文件 csdn-sign-in.yml 直接和源碼一起提交,GitHub 會自動識別,注意路徑為:.github\workflows\csdn-sign-in.yml。
以上步驟完成之后,再參考步驟【06x01】,完成參數設置即可。
總結
以上是生活随笔為你收集整理的Python + GitHub Actions 实现 CSDN 自动签到与抽奖(非 selenium 版本)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 余承东大赞舒适度超越所有豪车!问界M7实
- 下一篇: 邀请粉丝设计手机!魅族19主理人首批渲染