如何解放双手,自动在洛谷打卡?

· · 科技·工程

免责声明:本项目仅供技术学习与交流使用。使用者在使用本项目时应遵守洛谷用户协议。严禁使用本项目进行攻击、高频抓取或任何干扰洛谷正常运行的行为。作者不对使用本项目导致的账号封禁或 Cookie 泄露负责。

为遵守相关服务条例,目前本项目并未在 GitHub Actions 设定定时自动化。仅手动运行进行集成测试。

本文不实时更新,请前往仓库跟进最新进度。

upd:被撤了/kel

由于自动登录账号很难,我们考虑先在登陆好的账号上开始写。

先手动 F12 从网络请求里的 Request Headers 找到自己 cookie。

格式例如 cookie_str = "_uid=646208; __client_id=****************************************; C3VK=******"

(关键信息已经打码,不要迫害我 qwq)

手动点一下打卡,看眼打卡的网络请求,可以发现打卡按钮干的事情是请求 https://www.luogu.com.cn/index/ajax_punch 这个网址。

本来自己搓了个土制请求结果死活返回 418,生气。问了下好像是 CloudFlare 干的,怄火。

在 Gemini 的建议下,请求里做了个伪装,假装自己其实是 Chrome 浏览器,并且将 Referer 设置成了洛谷主页。

可以写出这样的请求:

headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Cookie":cookie_str,
    "Referer":"https://www.luogu.com.cn/",
    "x-requested-with":"XMLHttpRequest" 
}

然后我们尝试一下发一个 GET 请求并且解析一下 JSON。如果解析成功了就表示发成功了,然后看眼它的状态码,如果是 200 表示打卡成功了,201 表示已经打过卡了。

拿小号做的测试,成功了返回的 JSON 数据是:

{'code': 200, 'message': '', 'more': {'html': '<h2 style=\'margin-bottom: 0\'><a class=\'lg-fg-gray\' href="/user/******"  target="_blank">******</a> 的运势</h2><span class="lg-punch-result lg-fg-green">§ 中平 §</span><div class="am-g">\n    <div class="am-u-sm-6 lg-fg-red">\n                    <span class="lg-bold">宜:</span>玩网游<br>\n            <span class="lg-small">犹如神助</span><br>\n            <span class="lg-bold">宜:</span>放假<br>\n            <span class="lg-small">自由自在的一个假期</span>\n        \n\n    </div>\n    <div class="am-u-sm-6">\n                    <span class="lg-bold">忌:</span>请教问题<br>\n            <span class="lg-small">被当作 xxs</span><br>\n            <span class="lg-bold">忌 :</span>装逼<br>\n            <span class="lg-small">被识破</span>\n            </div>\n    <div class="am-u-sm-12 lg-small">\n        &nbsp;<br>\n        你已经在洛谷连续打卡了 <strong>1</strong> 天</strong><br>\n    </div>\n</div>\n'}}

(其中用户名和 uid 已经打码)

如果已经打过卡了返回的则是:

{'code': 201, 'message': '今天你已经打过卡了哦,要一步一个脚印,不能急于求成!'}

判断一下响应的 status_code 是多少就可以啦~

以下给出完整代码:

import requests
import os
import sys

def luogu_punch():
    cookie_str="_uid=646208; __client_id=****************************************; C3VK=******" # 这行自己改
    url="https://www.luogu.com.cn/index/ajax_punch"
    headers={
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
        "Cookie":cookie_str,
        "Referer":"https://www.luogu.com.cn/",
        "x-requested-with":"XMLHttpRequest" 
    }
    try:
        print("正在尝试连接洛谷服务器...")
        response= requests.get(url,headers=headers,timeout=10)
        # print(response)
        try:
            data=response.json()
        except:
            print("解析 JSON 失败")
            return
        if response.status_code==200:
            code=data.get('code')
            if code==200:
                print(f"打卡成功,运势: {data}")
            elif code==201:
                print("今天已经打过卡了")
            else:
                print(f"失败: {data.get('message')}")
        else:
            print(f"状态码错误: {response.status_code}")
    except Exception as e:
        print(f"发生异常: {e}")

if __name__=="__main__":
    luogu_punch()

后续更新请参见俺做的仓库,求点个 star 吧。