白嫖微软服务器:全自动监控法国 ANEF 居留申请状态
在法国的小伙伴都知道,ANEF(外管局)的居留申请状态更新极其佛系。每天手动登录那个加载缓慢、经常报错的官网去查看进度,简直是一种精神折磨。
之前我尝试过在自己的小内存 VPS 上跑无头浏览器监控,结果内存分分钟爆满。最终,我走通了一条高大上的路子——利用 GitHub Actions 免费服务器进行全自动监控,每天准时发邮件播报状态。
本文将手把手教你如何搭建这套零内耗、零成本的监控系统。
核心原理:为什么选择 GitHub Actions?
GitHub Actions 是微软推出的 CI/CD 服务,它允许你在其托管的虚拟机上运行自定义脚本。
对于我们这个需求,它的优势简直是完美的:
- 完全免费:私有仓库每个月有 2000 分钟的免费额度,每天跑一次监控任务(约消耗 1 分钟),根本用不完。
- 零内耗:不需要占用你自己服务器的任何 CPU 或内存。
- 环境标准:微软提供的 Ubuntu 环境极其标准,Playwright(无头浏览器)运行非常稳定。
- 反爬虫友好:ANEF 的防火墙(如 Cloudflare)对小厂 VPS 的 IP 非常敏感,但对大厂(微软)的 IP 段相对宽容。不过,这也是唯一的潜在风险点:如果微软云的 IP 被防火墙拉黑,脚本就会失效。目前来看,值得一试。
核心挑战:ANEF 精确登录
ANEF 的登录系统使用的是 Keycloak 单点登录(SSO)。传统的账号密码模拟往往会因为动态 Token 或加载缓慢而失败。
为了提高稳定性,我深入分析了 ANEF 的 SSO 授权链,找到了直接访问底层授权直链的方法,跳过了主页花里胡哨的动画,直接访问登录表单,大大提高了成功率。
部署指南:10 分钟彻底解放
第一步:准备发件邮箱(以 Gmail 为例)
为了保证邮件能 100% 发送成功,建议使用 Gmail、QQ 邮箱、163 邮箱等主流邮箱作为发件箱。由于 GitHub Actions 的安全性限制,你绝对不能在代码里使用你的原密码,必须使用 应用专用密码 (App Password)。
- Gmail 用户:登录谷歌账户 -> 安全 (Security) -> 开启两步验证 -> 搜索 “应用密码” -> 生成一个名为
anef-monitor 的密码,复制那一串 16 位字母。 - QQ/163 邮箱用户:进入邮箱设置 -> 账户 -> 开启 SMTP 服务 -> 会获得一串授权码。
第二步:创建 GitHub 私有仓库
- 登录你的 GitHub 账号。
- 新建一个仓库(Repository),名字随便起(比如
anef-visa-monitor)。 - 【最重要的一步】 仓库可见性务必选择 Private(私有)!否则你的账号密码、API 数据都会被公开。
第三步:配置 Secrets 环境变量
这是为了将你的账号密码安全地存入 GitHub 的加密库中,脚本能读取到,但外人看不到。
- 在仓库主页点击 Settings。
- 左侧菜单展开 Secrets and variables -> Actions。
- 点击 New repository secret,依次添加以下 5 个机密变量:
| Secret 名字 | Value (填写内容) | 说明 |
|---|
ANEF_EMAIL | your_anef_email@xxx.com | 您登录 ANEF 的账号 |
ANEF_PWD | your_anef_password | 您登录 ANEF 的密码 |
SMTP_USER | sender@gmail.com | 发信邮箱账号(比如您的 Gmail) |
SMTP_PWD | abcd efgh ijkl mnop | 刚刚获取的邮箱应用密码/授权码 |
NOTIFY_EMAIL | receiver@xxx.com | 您自己用来接收通知的邮箱(可以和发信邮箱相同) |
第四步:编写 Python 自动化脚本 (monitor.py)
在仓库主页点击 Add file -> Create new file,文件名输入 monitor.py,然后粘贴以下精确定位的优化代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| import os import time import smtplib from email.mime.text import MIMEText from playwright.sync_api import sync_playwright
ANEF_EMAIL = os.environ.get("ANEF_EMAIL") ANEF_PWD = os.environ.get("ANEF_PWD") SMTP_USER = os.environ.get("SMTP_USER") SMTP_PWD = os.environ.get("SMTP_PWD") NOTIFY_EMAIL = os.environ.get("NOTIFY_EMAIL")
SMTP_SERVER = "smtp.gmail.com" SMTP_PORT = 465
SSO_LOGIN_URL = "喝咖啡备注联系方式发送" API_URL = "喝咖啡备注联系方式发送"
def send_email(content, subject="【ANEF 居留状态通知】"): """邮件发送模块""" msg = MIMEText(content, 'plain', 'utf-8') msg['Subject'] = subject msg['From'] = SMTP_USER msg['To'] = NOTIFY_EMAIL try: server = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) server.login(SMTP_USER, SMTP_PWD) server.sendmail(SMTP_USER, [NOTIFY_EMAIL], msg.as_string()) server.quit() print("邮件通知发送成功!") except Exception as e: print(f"邮件发送失败: {e}")
def run_monitor(): """监控核心模块""" with sync_playwright() as p: browser = p.chromium.launch(headless=True) context = browser.new_context( 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", locale="fr-FR", timezone_id="Europe/Paris" ) page = context.new_page()
try: print("1. 正在访问 ANEF SSO 登录直链...") page.goto(SSO_LOGIN_URL, timeout=60000) print("2. 正在精确定位表单并填写账号密码...") page.wait_for_selector("input[name='username']", timeout=20000) page.fill("input[name='username']", ANEF_EMAIL) page.fill("input[name='password']", ANEF_PWD) print("3. 点击登录按钮提交表单...") page.click("button[type='submit']") print("4. 正在智能等待重定向归位...") page.wait_for_url("**/usagers/**", timeout=30000) time.sleep(3) print("5. 身份校验成功!直调核心数据 API...") page.goto(API_URL) result_data = page.locator("body").inner_text() if "error" in result_data.lower() or "forbidden" in result_data.lower(): send_email(f"API 拒绝访问,可能防火墙拦截,返回原始内容:\n\n{result_data}", "【异常】ANEF 监控接口失效") else: send_email(f"恭喜,成功获取居留申请最新数据:\n\n{result_data}", "【更新】ANEF 居留申请状态播报") except Exception as e: send_email(f"自动化脚本执行遇到未知错误,可能是网页改版或遭遇图形验证码:\n\n{str(e)}", "【崩溃】监控脚本执行失败") finally: browser.close()
if __name__ == "__main__": run_monitor()
|
第五步:配置定时任务 (daily-check.yml)
最后,我们需要告诉 GitHub Actions 在每天什么时候跑这个脚本。
在仓库里点击 “Add file” -> “Create new file”。
在文件名的框里完整输入:.github/workflows/daily-check.yml (注意路径和点,这会让 GitHub 识别为标准的工作流控制文件)。
粘贴以下工作流代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| name: Daily ANEF Monitor
on: schedule: - cron: '0 7 * * *' workflow_dispatch:
jobs: run-monitor: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v4
- name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.10'
- name: Install Dependencies run: | pip install playwright playwright install chromium
- name: Run Monitor Script env: ANEF_EMAIL: ${{ secrets.ANEF_EMAIL }} ANEF_PWD: ${{ secrets.ANEF_PWD }} SMTP_USER: ${{ secrets.SMTP_USER }} SMTP_PWD: ${{ secrets.SMTP_PWD }} NOTIFY_EMAIL: ${{ secrets.NOTIFY_EMAIL }} run: python monitor.py
|
祝顺利下卡!
提交保存完成后,你就可以在 Actions 标签页下点击 “Run workflow” 来强行触发测试了。
如果一切顺利,从今天起,你将彻底告别 ANEF 那个卡顿的登录界面,在每天早餐时分,安静地等待邮件通知最新的居留申请状态。祝你的居留申请早日收到卡!