整个迁移分四步:导出内容、转成 Markdown、重写链接、搬走图片。听着不难,实际每一步都卡了一阵。
第一步:导出
WordPress 后台自带的导出工具会生成一个 WXR 文件——本质是一个大 XML,里面是文章、页面、分类、标签和评论。
Warning
导出前先把插件全部关掉。某些 SEO 插件会在正文里注入短代码,导出来的 Markdown 会混进一堆 [wpseo_breadcrumb] 之类的东西,清理起来很痛苦。
第二步:转 Markdown
现成的转换器有几个,但都不能指望一步到位。转换后必然要手工处理这几类问题:
- frontmatter 缺字段 ——
pubDatetime、description、tags经常是空的,得补 - 图片路径还是绝对 URL —— 指向旧域名的
/wp-content/uploads/... - HTML 标签残留 —— WordPress 的古腾堡区块会留下
<figure>、<div class="wp-block-*"> - 代码块被转义 —— 尖括号变成
<,得反转义回来
# 批量反转义尖括号
find src/content/posts -name "*.md" -exec sed -i \
-e 's/</</g' -e 's/>/>/g' -e 's/&/\&/g' {} +
第三步:重写链接
这一步最容易被低估。WordPress 的默认固定链接是 /2024/03/slug/,而 Astro 主题通常是 /posts/slug/。
Important
老链接一旦 404,之前积累的搜索排名和外部反链就全废了。 迁移前一定要把旧站点的 URL 结构导出来,逐条做重定向映射。
两个办法:
| 方案 | 做法 | 适用场景 |
|---|---|---|
| 在主题里改路由 | 让新站直接用 /yyyy/mm/slug/ 结构 | 链接结构规整,改动小 |
| 加重定向规则 | 在 CDN 或 _redirects 里配 301 | 结构混乱,或者已经换过好几套 |
推荐优先考虑第一种。301 跳转虽然对 SEO 友好,但每个访客都要多走一次请求。
第四步:搬图片
wp-content/uploads/ 通常会占整个站点体积的 80% 以上。我这边是 78MB,全是历史文章里的截图。
处理方式取决于图片数量:
- 几十张 —— 直接放进
public/,随站点一起部署 - 几百张以上 —— 放对象存储(R2 / OSS),走独立域名 + CDN
- 特别老的截图 —— 考虑批量转 WebP,体积能砍掉六七成
Tip
迁移完先别急着关掉旧站。挂一个月的 301 跳转,观察搜索引擎的抓取日志确认没有大面积 404,再下线也不迟。
最后
整个迁移花了一个周末。内容本身是干净的,麻烦的全是那些「历史遗留」——十年前随手插的短代码、改过三次的固定链接、散落在正文里的外链图片。
所以如果现在正在用 WordPress 且不打算迁移,至少把固定链接结构定下来别再改,未来会谢自己。