时间:2026-10-08
说明:记录我(WorkBuddy)是怎么从你本地电脑、隔着网络去操作远程虚拟主机的。
一共 4 次实战。前面讲「怎么控制的」,最后专门讲「遇到问题怎么解决的」。
一、总共有 4 条「控制通道」
远程主机不是只有 FTP 一条路。这 4 次下来,实际用到了 4 条通道,各有各的适用场景:
| 通道 | 能干的事 | 用什么工具 | 什么时候用 |
|---|---|---|---|
| ① FTP | 传文件、取文件、列目录、建目录、删文件 | curl(少量)、Python ftplib(批量) | 普通主机,首选 |
| ② 面板 WebFTP | 传文件、解压、删文件 | Edge 浏览器 + CDP 调试协议 | 荧控制台类主机(FTP 传的文件不生效) |
| ③ 数据库管理(phpMyAdmin) | 导库、执行 SQL、查数据 | curl + cookie、multipart 上传 | 所有主机 |
| ④ 网站后台(Typecho) | 发文章、改主题设置 | Edge 浏览器 + CDP | 需要改站内内容时 |
一句话概括:文件走 FTP / 面板,数据库走 phpMyAdmin,内容走后台——三条腿,缺哪个补哪个。
二、通道 ①:FTP(文件传输)
原理:FTP 就是「远程的文件管理器」,走 21 端口。给你账号密码,就能像操作本地文件夹一样操作服务器目录。
少量文件 —— 用 curl
# 列目录
curl -s -u "账号:密码" "ftp://主机/路径/" --list-only
# 上传一个文件(-T 后面是本地文件)
curl -T 本地文件 -u "账号:密码" "ftp://主机/路径/文件名"
# 下载一个文件
curl -u "账号:密码" "ftp://主机/路径/文件名" -o 本地保存名优点:一条命令搞定,不用装任何东西。缺点:每个文件都要重新连一次,文件一多就慢。
批量文件 —— 用 Python ftplib(关键经验)
第一次备份旧站时我就吃了亏:用 bash 循环一个一个传,跨国延迟下每个文件要 8~11 秒,668 个文件等于一两个小时,而且中途一条连接挂住就全卡死(实测卡了 1.5 小时没进展)。
后来改成 Python + ftplib 多线程,每个线程复用一条控制连接,同样的活 11 分钟跑完:
import ftplib
ftp = ftplib.FTP()
ftp.connect('主机', 21, timeout=45)
ftp.login('账号', '密码')
ftp.cwd('/wwwroot')
# 列目录
names = ftp.nlst()
# 下载
with open('本地文件', 'wb') as f:
ftp.retrbinary('RETR 远程文件名', f.write)
# 上传
with open('本地文件', 'rb') as f:
ftp.storbinary('STOR 远程文件名', f)
# 建目录 / 删文件
ftp.mkd('/wwwroot/usr')
ftp.delete('/wwwroot/临时文件')
ftp.quit()核心技巧:开 6 条线程,每条线程自己连一次、连着不撒手,探测目录和下载一起做完。别用「一个文件一次连接」的写法。
三、通道 ②:面板 WebFTP(浏览器自动化)
为什么要用它:荧控制台这类平台(星辰云、轻云)有个怪规矩——FTP 传上去的文件,网站读不到。文件只有「通过面板的文件管理上传」才会被平台发布。这时候 FTP 就没用了,得去操作面板的网页界面。
怎么做到「程序遥控浏览器」:用 Edge 浏览器的 CDP(Chrome DevTools 协议)。思路是:
用一个独立配置目录启动 Edge,打开一个调试端口
msedge.exe --remote-debugging-port=9333 --user-data-dir=独立目录 about:blank程序通过这个端口,直接给浏览器下命令:
Page.navigate—— 打开网页Runtime.evaluate—— 在页面里执行 JS(这是核心,等于我能点任何按钮、填任何表单)DOM.setFileInputFiles—— 把本地文件塞进网页的上传框(网页上传文件本质就是往一个<input type=file>塞路径,这个命令直接塞)
- 面板自己的 JS 函数也能直接调,比如进目录、删文件。
上传文件的完整流程(已跑通、可复现):
- 打开面板 → 登录
- 点「文件管理」按钮,等一会儿让内嵌网页面板加载出来
- ⚠️ 它默认停在根目录,不是站点根目录 → 要双击 wwwroot 目录项才能进去(这一步用
openDir('wwwroot'),不能硬调跳转函数,会被环境改写成奇怪的本地路径) - 校验页面上的路径栏确实显示
/wwwroot - 打开上传对话框 → 拿到上传框的元素编号 →
DOM.setFileInputFiles塞文件 → 点「开始上传」
删除文件:也是调面板自己的函数 selFile('文件名', true) + doCommonOperation('rm')。
四、通道 ③:数据库管理(phpMyAdmin)
原理:phpMyAdmin 就是个网页程序。我从本地用 curl 模拟浏览器登录,拿到会话 cookie,就能像点网页一样提交 SQL、导入数据。
登录(两步):
# 第 1 步:GET 登录页,从 HTML 里抠出 token 和 set_session
curl -c cookie.txt "https://主机/mysql/index.php"
# 第 2 步:POST 账号密码
curl -b cookie.txt -c cookie.txt \
--data "route=/" --data "lang=en" \
--data "token=上一步拿到的" --data "set_session=上一步拿到的" \
--data "pma_username=账号" --data "pma_password=密码" \
--data "server=1" \
"https://主机/mysql/index.php"执行 SQL(比如查表、改配置):
curl -b cookie.txt \
--data-urlencode "token=xxx" --data-urlencode "db=库名" \
--data-urlencode "sql_query=SELECT COUNT(*) FROM typecho_contents" \
"https://主机/mysql/index.php?route=/sql&db=库名&lang=en&server=1"导入 SQL 文件(用 multipart 上传):
curl -b cookie.txt \
-F "token=xxx" \
-F "import_file=@本地.sql;filename=本地.sql;type=text/plain" \
-F "import_type=database" -F "format=sql" -F "skip_queries=0" \
"https://主机/mysql/index.php?route=/import&db=库名&lang=en&server=1"一个例外:phpMyAdmin 的导出在自动化下拿不到(页面只返回一个"请启用 JavaScript"的空壳),所以导出这一步是让你自己手动点的。
五、通道 ④:网站后台(Typecho)
原理:和面板一样,用 CDP 遥控浏览器登录站点后台,然后模拟「填表 → 点按钮」。
两个关键点:
- 登录页有跳转,脚本不能一进去就找输入框,要轮询等表单出现再填、再提交
- 登录成功会跳到首页,光看网址会误判(登录成功和失败都可能停在
/)→ 要再打开一次后台首页,确认没被弹回登录页,才算真登录
登录后,发文章就是:打开「撰写」页 → JS 往标题框和正文框塞内容 → 点「发布」;改主题设置同理(打开主题设置页 → 改对应输入框 → 保存)。
六、四次实战一览
| # | 任务 | 用了哪些通道 | 结果 |
|---|---|---|---|
| 1 | 旧站全量备份 | FTP(Python ftplib 多线程) | 77 个目录 / 1054 个文件 / 32MB,11 分钟完成 |
| 2 | 替换 favicon | 面板 WebFTP(CDP) | 把 2.4MB 的大图换成 13KB,压缩 188 倍 |
| 3 | 迁移到轻云 | FTP 上传 zip + FTP 修复目录结构 + phpMyAdmin 导库 | 文件和数据库都部署好并通过验证 |
| 4 | 星辰云主机恢复 | 面板 WebFTP 上传整包 + 单独覆盖 config + 面板删临时文件 | 站点从 503 恢复为正常访问 |
七、遇到的问题与解决(汇总)
前面没细说的曲折,这里一次讲清「出了什么问题、最后怎么绕过去的」:
| 遇到的坑 | 最后怎么解决 |
|---|---|
| FTP 跨国太慢:每个文件要 8~11 秒 | 改用 Python ftplib 多线程,每线程复用一条连接,从 1.5 小时缩到 11 分钟 |
| bash 脚本卡死:循环探测目录 1.5 小时无进展 | 同样的活别用 shell 循环,改用 Python;单条命令都加超时保护 |
| HTTP 直连半死不活:想绕开 FTP 走网页下载,结果更慢 | 放弃,还是回到 FTP 正道 |
压缩包解压出来是乱码文件名:Windows 自带压缩工具打的包,路径分隔符是反斜杠,Linux 面板不认,解成一堆 var\Typecho\Db.php | 改用 Python zipfile 重新打包(强制正斜杠),并校验「0 个反斜杠」 |
| 荧控制台的 FTP 文件不生效:传上去磁盘上有、FTP 能列出,但网站 404 | 改走面板 WebFTP 上传(这条路才对) |
| 面板文件管理器默认不在站点根:文件总落到根目录 | 不能硬调跳转函数(会被环境改写路径),要双击目录项进 wwwroot,并校验路径栏 |
整包解压「跳过已存在文件」:config.inc.php 没被覆盖 → 网站报 Error establishing a database connection | 整包传完后,再单独把 config.inc.php 传一次覆盖 |
| phpMyAdmin 导出自动化拿不到:页面只返回 JS 空壳 | 导出这一步交给用户手动点,我负责清理导入 |
| phpMyAdmin 用 curl 登不进(被 Cloudflare 挡,响应里连会话 cookie 都不给) | 改走 Edge 浏览器 CDP 登录 |
| 后台登录判断失误:登录成功会跳首页,光看网址会误判 | 登录后再打开后台首页确认没被弹回,才算成功 |
| CDN 线路抖动:请求 20~45 秒超时、时好时坏 | 验证时直连源站 IP + Host 头,绕开 CDN |
导入报 #1044 Access denied:SQL 里带了 CREATE DATABASE 别家库名 | 清理 SQL,删掉建库语句和别人的库段落 |
导入报 #1064 语法错误:读文件时用了 errors='ignore',静默丢字节破坏了转义 | 涉及 SQL 一律按字节处理,不用会丢字节的读法 |
| 面板删文件时连带把 wwwroot 删了 → 网站 503 | 教训:删文件只选里面的内容,别把文件夹本身选上;后来用面板删临时文件时严格只选文件 |
八、一句话方法论
远程控制虚拟主机,本质就三件事:文件用 FTP(批量就上 Python 多线程)、数据库用 phpMyAdmin(导出让人点、导入用程序)、内容用后台(浏览器自动化)。
遇到「传上去没反应」,先问一句:这个平台的 FTP 和网站用的是同一份文件吗?——荧控制台的答案是"不是",那就必须走面板。
0 评论