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
的解决方案非常巧妙,它没有去尝试图像识别缺口位置,而是走了另一条“捷径”。
-
定位关键数据
:脚本通过分析页面加载的
longbow.slidercaptcha.js这个验证码库的源代码,发现滑块缺口真正的水平坐标x值,存储在验证码实例的一个属性里(代码中体现为instance.x)。这意味着,答案其实就写在“考卷”上。 -
拦截与计算
:脚本通过猴子补丁的方式,劫持了验证码组件内部用于验证的AJAX请求。当用户拖动滑块触发验证时,脚本能提前获取到服务端返回的验证结果,并结合之前获取的
instance.x值,计算出需要滑动的精确像素距离。 - 模拟人类拖动 :得到精确距离后,脚本并没有让鼠标“瞬移”过去,而是模拟了人类的拖动行为:先快速滑动一大段,然后缓慢微调,最后可能还有一点回弹。这种非匀速的、带有加速度和轻微抖动的轨迹,能够有效绕过基于轨迹分析的检测模型。
重要提示 :这种技术本质上是在与网站的安全机制“对抗”。虽然该项目仅用于个人便捷化填表,且数据最终提交至合法官网,但你必须清楚,未经授权对网站进行自动化操作,特别是绕过其安全验证机制,可能违反该网站的服务条款。此处的技术解析仅供学习交流,请确保你的使用行为符合相关规定,并尊重网站运营方的权益。
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,集成过程大致如下:
-
Skill配置
:你需要按照OpenClaw Skill的规范,编写一个
skill.yaml描述文件,定义这个Skill的名称、描述、触发指令(如“填写马来西亚入境卡”)、所需的参数(姓名、护照号等)以及最终要执行的命令(即调用本地的Python脚本)。 -
参数映射
:当你在AI助手界面说“帮我填MD卡,姓名张三,护照A12345678...”,AI助手会解析这些自然语言,并将其转化为结构化的JSON数据,传递给后台的
fill_and_submit.py脚本。 - 安全调用 :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. 查看垃圾邮件文件夹。
|
5.2 关于安全与隐私的再思考
任何涉及自动化处理个人身份信息的工具,安全都是头等大事。
mdac-filler
在安全方面做了几个关键设计:
- 数据流透明 :所有代码开源,你可以清晰看到,数据仅在最终提交时通过浏览器发送至MDAC官方域名,中间没有经过任何代理或第三方服务器。脚本本身不具备网络传输功能来外泄你的数据。
- 本地化运行 :整个流程在你的电脑上完成,这是最大的安全保障。你的护照信息不会上传到任何“云端服务”。
-
配置文件权限
:强调使用
chmod 600保护JSON文件,这是防止同一台电脑上的其他用户窃取信息的基本操作。
然而,风险并未完全消失:
- 恶意修改风险 :如果你从不可信的来源下载了被篡改的脚本,那么它可能在你不知情的情况下窃取信息。 始终从官方仓库克隆代码 ,并在运行前花几分钟浏览核心脚本,确保没有可疑的网络请求。
-
终端历史记录
:即使使用
--file,如果你在命令行中补全了文件名,敏感路径仍可能被记录。可以在命令前加一个空格(取决于Shell配置),或定期清理Shell历史。 - 法律与条款风险 :这是最容易被忽视的一点。自动化提交可能违反MDAC网站的使用条款。虽然该项目目的是为了方便,且最终提交了真实有效的信息,但从技术上讲,这仍是一种“未经授权的自动化访问”。你需要自行评估和承担由此可能产生的风险。
5.3 工具的局限性与未来扩展方向
没有任何工具是万能的,
mdac-filler
也不例外。认清它的局限,才能更好地使用它:
- 网站变更即失效 :这是所有网页自动化工具的阿喀琉斯之踵。马来西亚移民局只要对前端代码稍作改动,特别是验证码部分,脚本就可能立即失效。工具维护者需要持续关注并更新。
- 无法处理异常情况 :如果提交过程中网络突然中断,或者网站返回一个意外的错误页面(如“系统维护中”),脚本可能无法智能处理,导致提交状态未知。
- 仅适用于固定流程 :它严格遵循“填写-验证-提交”的线性流程。如果MDAC新增了步骤(如短信验证),当前脚本无法适应。
基于这些局限,如果你有兴趣深入开发或定制,可以考虑以下几个扩展方向:
- 增加重试与容错机制 :在验证码失败或网络超时时,自动重试若干次。
-
开发配置化选择器
:将HTML元素选择器(如
#passNo)提取到外部配置文件中,这样网站改版时,用户只需更新配置文件,而无需修改Python代码。 - 添加状态通知 :集成邮件或即时通讯工具(如Telegram Bot)的API,在提交成功或失败时,主动发送通知到你的手机。
- 容器化部署 :使用Docker将整个环境打包,真正做到一键运行,彻底解决“在我电脑上好好的,在你那就报错”的环境依赖问题。
这个项目是一个很好的起点,它展示了一个具体的需求如何通过一系列开源技术栈被优雅地解决。它的价值不仅在于节省了那几分钟,更在于提供了一种思路:用技术将人们从重复、枯燥的数字流程中解放出来。
