1. 项目概述:一个专为跨境通勤者设计的自动化填表工具

如果你和我一样,经常需要往返于新加坡和马来西亚新山之间,那你一定对那个蓝色的马来西亚数字入境卡网站再熟悉不过了。每次出发前,都得花上宝贵的5到10分钟,像个机器人一样重复填写姓名、护照号、出生日期、地址……更别提那个总让人心烦意乱的滑块验证码了。这种重复性劳动,对于每周甚至每天都要跨境通勤的人来说,简直是时间杀手。

相关服务:马来西亚大带宽服务器租用

今天要聊的这个项目, mdac-filler ,就是为解决这个痛点而生的。它不是什么复杂的商业软件,而是一个用Python写的自动化脚本,核心思路非常简单:把你每次都要手动输入的信息交给程序,让它去替你完成所有繁琐的点击、填写和提交动作。你可以把它理解为一个高度定制化的“按键精灵”,但专门针对马来西亚移民局的官方MDAC网站。

这个工具的价值,对于高频跨境者来说是显而易见的。它节省的不仅仅是那几分钟的操作时间,更是消除了行前准备中的一个心理负担——你再也不用担心因为匆忙填错信息,或者被验证码卡住而耽误行程。整个工具完全本地运行,你的护照、邮箱等敏感信息只会上传到MDAC官网,不会经过任何第三方服务器,这在设计上就考虑到了隐私和安全。

接下来,我会带你从零开始,完整地拆解这个工具的运作原理、部署方法、使用技巧,并分享我在实际使用和测试过程中踩过的坑和总结的经验。无论你是Python新手,还是有一定经验的开发者,都能从中找到可以直接“抄作业”的部分。

2. 核心原理与技术栈深度解析

2.1 为什么选择Playwright作为自动化核心?

市面上浏览器自动化工具不少,老牌的Selenium,轻量的Puppeteer,那为什么 mdac-filler 选择了Playwright呢?这背后有几个非常实际的考量。

首先, 兼容性与反检测能力 。MDAC作为政府官方网站,其前端虽然不算复杂,但可能会有一些基础的防机器人检测机制。Playwright相比Selenium的一个巨大优势在于,它能够更好地模拟真实的人类浏览器环境。它通过注入一些特定的JavaScript执行痕迹和修改WebDriver属性,使得被检测为“自动化浏览器”的概率大大降低。项目特意使用了非无头模式启动浏览器,就是为了让整个操作过程在视觉上完全像一个真实用户在操作,进一步规避风险。

其次, 可靠的选择器与等待机制 。Playwright提供了非常强大的选择器引擎,支持CSS、XPath、文本内容等多种定位方式,并且内置了智能等待。这对于MDAC这种表单页面至关重要,因为页面元素可能因为网络加载速度而出现时间差。Playwright的 page.wait_for_selector 或 page.wait_for_function 可以确保在元素真正可交互时才进行操作,避免了因页面未加载完成而导致的填充失败。

最后, 跨平台与易用性 。Playwright支持Windows、macOS、Linux三大主流操作系统,并且安装配置一气呵成。一条 playwright install chromium 命令就能搞定浏览器驱动,对用户极其友好。这对于一个旨在降低使用门槛的工具来说,是决定性的优势。

2.2 表单填充策略:从粗暴注入到精准模拟

自动填表听起来简单,但要做好却有不少门道。最直接的方法是用JavaScript直接设置输入框的 value 属性,就像项目里做的: document.getElementById(‘passNo’).value = ‘A12345678’ 。这种方法高效、直接,但存在一个潜在问题:某些网站会监听输入框的 input 或 change 事件来触发后续逻辑(比如实时校验、联动下拉框等)。如果只是设置 value ,可能无法触发这些事件。

mdac-filler 目前采用的就是这种直接注入的方式。经过实测,MDAC的表单没有复杂的即时校验逻辑,所以这种方法完全可行且稳定。但如果你要把这个思路应用到其他网站,就需要留意了。更健壮的做法是模拟真实用户的键盘输入,使用Playwright的 page.type() 或 page.fill() 方法。 page.fill() 会先清空内容再输入,并触发相关事件,通常更接近人工操作。在项目的代码中,开发者选择了性能更优、代码更简洁的JS注入,这是在对目标网站行为有充分把握后做出的合理取舍。

2.3 滑块验证码破解:技术分析与伦理边界

这是整个项目最技术核心,也最引人关注的部分——自动破解拼图滑块验证码。常见的滑块验证码防御思路是分析鼠标移动轨迹,如果轨迹是匀速直线,就会被判定为机器操作。 mdac-filler 的解决方案非常巧妙,它没有去尝试图像识别缺口位置,而是走了另一条“捷径”。

  1. 定位关键数据 :脚本通过分析页面加载的 longbow.slidercaptcha.js 这个验证码库的源代码,发现滑块缺口真正的水平坐标 x 值,存储在验证码实例的一个属性里(代码中体现为 instance.x )。这意味着,答案其实就写在“考卷”上。
  2. 拦截与计算 :脚本通过猴子补丁的方式,劫持了验证码组件内部用于验证的AJAX请求。当用户拖动滑块触发验证时,脚本能提前获取到服务端返回的验证结果,并结合之前获取的 instance.x 值,计算出需要滑动的精确像素距离。
  3. 模拟人类拖动 :得到精确距离后,脚本并没有让鼠标“瞬移”过去,而是模拟了人类的拖动行为:先快速滑动一大段,然后缓慢微调,最后可能还有一点回弹。这种非匀速的、带有加速度和轻微抖动的轨迹,能够有效绕过基于轨迹分析的检测模型。

重要提示 :这种技术本质上是在与网站的安全机制“对抗”。虽然该项目仅用于个人便捷化填表,且数据最终提交至合法官网,但你必须清楚,未经授权对网站进行自动化操作,特别是绕过其安全验证机制,可能违反该网站的服务条款。此处的技术解析仅供学习交流,请确保你的使用行为符合相关规定,并尊重网站运营方的权益。

3. 从零开始的完整部署与配置指南

3.1 基础环境搭建与依赖安装

让我们一步步来,确保你的环境能顺利跑起来。首先,你需要Python环境。我推荐使用Python 3.8或以上版本,太老的版本可能对某些库支持不好。

打开你的终端,按顺序执行以下命令:

# 1. 克隆项目代码到本地
git clone https://github.com/YangXinlin/mdac-filler.git
cd mdac-filler

# 2. 创建并激活一个虚拟环境(强烈推荐,避免包冲突)
python -m venv venv
# 在Windows上激活:
venv\Scripts\activate
# 在macOS/Linux上激活:
source venv/bin/activate

# 3. 安装Playwright库
pip install playwright

# 4. 安装Chromium浏览器(Playwright将用它来运行)
playwright install chromium

这里有个小坑我踩过: 网络问题 。 playwright install chromium 这一步需要从Google的服务器下载Chromium浏览器,在国内网络环境下可能会非常慢甚至失败。解决办法有两个:一是使用可靠的网络代理;二是利用Playwright的镜像源,在安装时指定环境变量:

# 设置淘宝镜像源来下载浏览器(仅限下载浏览器二进制文件这一步)
set PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright
playwright install chromium

3.2 个人信息配置文件详解与安全实践

直接通过命令行 --data 参数传递个人信息是极不安全的,因为命令行历史会被记录。项目推荐使用JSON配置文件,这是非常正确的做法。

首先,在项目根目录下创建一个名为 my_info.json 的文件。你可以参考项目 references/ 目录下的示例,但为了更清晰,我为你整理了一个带详细注释的模板:

{
  “name”: “ZHANG SAN”,
  // 注意:姓名必须与护照上完全一致,通常是大写拼音。
  “passNo”: “A12345678”,
  // 护照号码,注意字母大小写。
  “nationality”: “CHN”,
  // 国籍代码。中国是‘CHN’,新加坡是‘SGP’。代码表可在项目references里找到。
  “pob”: “CHN”,
  // 出生地代码,通常与国籍相同。
  “dob”: “01/01/1990”,
  // 出生日期,格式必须是 DD/MM/YYYY。
  “sex”: “2”,
  // 性别:1为男性,2为女性。
  “passExpDte”: “01/01/2035”,
  // 护照有效期,格式 DD/MM/YYYY。
  “email”: “[email protected]”,
  “confirmEmail”: “[email protected]”,
  // 邮箱地址,用于接收提交成功的确认信,务必填写有效邮箱。
  “region”: “65”,
  // 电话号码国家区号,新加坡是65。
  “mobile”: “91234567”,
  // 马来西亚本地手机号(8位)。如果没有,可以填一个临时号码,但邮箱必须准确。
  “arrDt”: “25/03/2026”,
  // 抵达马来西亚的日期,格式 DD/MM/YYYY。必须在入境前3天内提交。
  “trvlMode”: “2”,
  // 旅行方式:1-空路,2-陆路,3-海路。从新山入境选2。
  “depDt”: “25/03/2026”,
  // 离开马来西亚的日期。如果是当天往返,就填和arrDt一样的日期。
  “embark”: “SGP”,
  // 出发地国家代码,从新加坡出发填‘SGP’。
  “vesselNm”: “Bus 170”,
  // 交通工具名称,例如‘Bus 170’, ‘Car’, ‘Flight MH123’。
  “accommodationStay”: “99”,
  // 在马来西亚停留天数。当天往返填1,过夜按实际填。‘99’是一个特殊值,代表‘其他’,通常用于不确定或复杂情况,但填实际天数更稳妥。
  “accommodationAddress1”: “106-108, Jalan Wong Ah Fook”,
  // 住宿地址第一行,通常写街道地址。
  “accommodationAddress2”: “Johor Bahru City Square”,
  // 住宿地址第二行,例如建筑名称、公寓号。
  “accommodationState”: “01”,
  // 州代码。柔佛州是‘01’。代码表见项目文档。
  “accommodationCity”: “0118”,
  // 城市代码。例如‘0118’对应‘JOHOR BAHRU’。务必与州代码匹配。
  “accommodationPostcode”: “80250”
  // 邮政编码。
}

创建好配置文件后, 至关重要的一步是设置文件权限 ,防止其他用户读取你的敏感信息:

chmod 600 my_info.json  # macOS/Linux
# 在Windows上,你需要通过文件属性面板设置,仅允许当前用户读写。

3.3 首次运行与验证

配置完成后,就可以进行首次试运行了。建议先不要用真实的近期行程信息,可以虚构一个未来的日期进行测试。

python3 scripts/fill_and_submit.py --file my_info.json

如果一切正常,你会看到一个新的Chromium浏览器窗口被打开,自动导航到MDAC网站,然后像有一只无形的手在操作一样,所有字段被迅速填充,滑块被自动拖动,最后表单提交。成功后,浏览器页面会显示“SUCCESSFULLY REGISTERED”的绿色提示,并且脚本会在控制台输出成功信息。

首次运行常见问题排查:

  • 浏览器启动失败 :检查Playwright Chromium是否安装成功,可以运行 playwright install --help 查看。确保没有其他程序占用着Chromium。
  • 页面元素找不到 :MDAC网站改版了?这是自动化脚本最大的风险。如果遇到,需要检查并更新脚本中的HTML元素选择器。你可以通过右键点击网页输入框,选择“检查”来查看其 id 或 name 属性。
  • 验证码滑动失败 :这是最可能出问题的环节。可能是验证码逻辑更新,导致脚本读取 instance.x 的方式失效。此时脚本可能会超时或报错。需要根据错误日志,分析新的验证码机制。

4. 高级使用技巧与场景化定制

4.1 集成到AI助手:OpenClaw Skill实战

mdac-filler 的一个亮点是它可以作为OpenClaw平台的一个Skill来使用。这意味着你可以通过自然语言指令,让你在ClawHub上的AI助手(比如基于Claude或Codex)来调用这个功能。

假设你已经部署好了自己的OpenClaw Agent,集成过程大致如下:

  1. Skill配置 :你需要按照OpenClaw Skill的规范,编写一个 skill.yaml 描述文件,定义这个Skill的名称、描述、触发指令(如“填写马来西亚入境卡”)、所需的参数(姓名、护照号等)以及最终要执行的命令(即调用本地的Python脚本)。
  2. 参数映射 :当你在AI助手界面说“帮我填MD卡,姓名张三,护照A12345678...”,AI助手会解析这些自然语言,并将其转化为结构化的JSON数据,传递给后台的 fill_and_submit.py 脚本。
  3. 安全调用 :Skill的执行通常在你的本地环境或受信任的服务器上,确保了个人信息不会泄露给第三方AI服务商。

这种方式的革命性在于,它将一个需要命令行操作的技术工具,变成了普通人用一句话就能完成的服务。你不需要记住JSON的格式,也不需要打开终端,只需像吩咐助理一样告诉AI你的需求。

4.2 为家人或团体批量提交

虽然脚本本身一次处理一个人的信息,但我们可以通过简单的Shell脚本或Python包装器来实现批量处理。思路是准备多个JSON文件(例如 person1.json , person2.json ),然后写一个循环脚本依次调用主程序。

创建一个 batch_submit.py 脚本:

import subprocess
import json
import os

# 假设所有JSON文件放在 ./profiles/ 目录下
profile_dir = “./profiles”
for filename in os.listdir(profile_dir):
    if filename.endswith(“.json”):
        filepath = os.path.join(profile_dir, filename)
        print(f“正在为 {filename} 提交MDAC...”)
        try:
            # 调用原脚本
            result = subprocess.run(
                [“python3”, “scripts/fill_and_submit.py”, “--file”, filepath],
                capture_output=True,
                text=True,
                timeout=120  # 设置超时,防止卡死
            )
            if result.returncode == 0:
                print(f“✅ {filename} 提交成功!”)
            else:
                print(f“❌ {filename} 提交失败。错误信息:{result.stderr}”)
        except subprocess.TimeoutExpired:
            print(f“⚠️ {filename} 处理超时,可能验证码失败或网络问题。”)
        print(“-” * 30)

重要提醒 :批量提交时,务必注意MDAC官网是否有频率限制。短时间内来自同一IP的多次提交可能会触发风控,导致后续提交需要额外的验证(如手机验证码)。建议在每次提交之间加入随机延迟(例如 time.sleep(random.uniform(10, 30)) ),模拟真人操作间隔。

4.3 字段映射与代码表维护

MDAC表单中有大量下拉菜单,其选项值不是文字,而是特定的代码。例如,国籍“中国”对应代码“CHN”,州“柔佛”对应“01”。项目中的 references/field-values.md 文件就是维护这些映射关系的“字典”。

作为用户,你需要关注这个文件。如果未来MDAC网站更新了选项(虽然不频繁),或者你需要填写之前没填过的国家/城市,就需要来这里查找或更新对应的代码。

作为开发者,如果你想将这个工具适配到其他国家的类似入境卡(例如澳大利亚的DPD、美国的EVUS),那么最关键的一步就是重新建立这份“字段-代码”映射表。你需要手动填写一次表单,用浏览器开发者工具抓取每个下拉框选项对应的 value 值。这个过程枯燥但必不可少,是自动化成功的基石。

5. 常见问题、故障排查与安全伦理探讨

5.1 运行时报错与解决方案速查表

在实际使用中,你可能会遇到以下问题。这里我整理了一个快速排查指南:

问题现象 可能原因 解决方案
ModuleNotFoundError: No module named ‘playwright’ Playwright Python包未安装。 在虚拟环境中执行 pip install playwright 。
Error: Browser chromium failed to launch Chromium浏览器未安装或安装损坏。 运行 playwright install chromium 重新安装。
脚本卡在“Navigating to MDAC website…”长时间不动 网络问题,无法访问MDAC官网。 检查本地网络,确认能否手动打开 https://imigresen-online.imi.gov.my 。
表单字段填充失败,控制台显示 Cannot find element MDAC网站HTML结构已更新。 1. 手动打开网站,检查对应输入框的 id 是否改变。
2. 修改 fill_and_submit.py 脚本中对应的元素选择器。
滑块验证码反复失败,最终超时 验证码算法或前端逻辑已更新。 这是最复杂的情况。需要分析新的 slidercaptcha.js 文件,找到存储缺口坐标的新变量或新验证逻辑,并更新脚本中的破解算法。
提交后页面显示错误(如日期无效、邮箱格式错误) JSON配置文件中的字段值格式不正确。 仔细检查JSON文件:日期是否为DD/MM/YYYY;邮箱是否有效;代码值是否在选项范围内。
成功提交但未收到确认邮件 邮箱填写错误,或邮件被归入垃圾邮件。 1. 检查JSON中的邮箱地址。
2. 查看垃圾邮件文件夹。

基于Playwright的自动化填表工具:破解滑块验证码与MDAC表单提交实战

3. 在MDAC网站尝试“检索提交”功能,用护照号和邮箱查询。

5.2 关于安全与隐私的再思考

任何涉及自动化处理个人身份信息的工具,安全都是头等大事。 mdac-filler 在安全方面做了几个关键设计:

  1. 数据流透明 :所有代码开源,你可以清晰看到,数据仅在最终提交时通过浏览器发送至MDAC官方域名,中间没有经过任何代理或第三方服务器。脚本本身不具备网络传输功能来外泄你的数据。
  2. 本地化运行 :整个流程在你的电脑上完成,这是最大的安全保障。你的护照信息不会上传到任何“云端服务”。
  3. 配置文件权限 :强调使用 chmod 600 保护JSON文件,这是防止同一台电脑上的其他用户窃取信息的基本操作。

然而,风险并未完全消失:

  • 恶意修改风险 :如果你从不可信的来源下载了被篡改的脚本,那么它可能在你不知情的情况下窃取信息。 始终从官方仓库克隆代码 ,并在运行前花几分钟浏览核心脚本,确保没有可疑的网络请求。
  • 终端历史记录 :即使使用 --file ,如果你在命令行中补全了文件名,敏感路径仍可能被记录。可以在命令前加一个空格(取决于Shell配置),或定期清理Shell历史。
  • 法律与条款风险 :这是最容易被忽视的一点。自动化提交可能违反MDAC网站的使用条款。虽然该项目目的是为了方便,且最终提交了真实有效的信息,但从技术上讲,这仍是一种“未经授权的自动化访问”。你需要自行评估和承担由此可能产生的风险。

5.3 工具的局限性与未来扩展方向

没有任何工具是万能的, mdac-filler 也不例外。认清它的局限,才能更好地使用它:

  • 网站变更即失效 :这是所有网页自动化工具的阿喀琉斯之踵。马来西亚移民局只要对前端代码稍作改动,特别是验证码部分,脚本就可能立即失效。工具维护者需要持续关注并更新。
  • 无法处理异常情况 :如果提交过程中网络突然中断,或者网站返回一个意外的错误页面(如“系统维护中”),脚本可能无法智能处理,导致提交状态未知。
  • 仅适用于固定流程 :它严格遵循“填写-验证-提交”的线性流程。如果MDAC新增了步骤(如短信验证),当前脚本无法适应。

基于这些局限,如果你有兴趣深入开发或定制,可以考虑以下几个扩展方向:

  1. 增加重试与容错机制 :在验证码失败或网络超时时,自动重试若干次。
  2. 开发配置化选择器 :将HTML元素选择器(如 #passNo )提取到外部配置文件中,这样网站改版时,用户只需更新配置文件,而无需修改Python代码。
  3. 添加状态通知 :集成邮件或即时通讯工具(如Telegram Bot)的API,在提交成功或失败时,主动发送通知到你的手机。
  4. 容器化部署 :使用Docker将整个环境打包,真正做到一键运行,彻底解决“在我电脑上好好的,在你那就报错”的环境依赖问题。

这个项目是一个很好的起点,它展示了一个具体的需求如何通过一系列开源技术栈被优雅地解决。它的价值不仅在于节省了那几分钟,更在于提供了一种思路:用技术将人们从重复、枯燥的数字流程中解放出来。