本文约 4,659 字,预计阅读 12 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:空壳站点最难的不是建,是填
很多人在本地把主题调得很漂亮,上线后面对的第一个真问题却是:栏目是空的。一个做机械配件的站点,产品中心下要铺 120 条型号说明,每条都有参数表、应用场景、配图,靠后台「文章 → 写文章」一条条贴,一个人要干两周,干到第三天就会开始复制粘贴、格式错位、分类漏选,最后产出一堆质量参差的页面,反而拖慢收录。
内容填充的效率瓶颈通常不在”打字速度”,而在三件事:字段怎么批量对齐、图片怎么跟着进媒体库、导入后怎么快速发现错误。这三件事解决掉,填充速度能提升一个量级。真正适合国内站长的方案有三条:用官方导入器迁移整站、用 WP All Import 把 Excel/CSV 映射成文章、用 WP-CLI 或自建脚本程序化写入。它们不是互斥关系,冷启动阶段往往是先用导入器搬存量,再用脚本补骨干部位。本文按”先能跑通,再谈规模”的顺序讲。
原理分析:三条路径各自的边界
三条路径的本质区别是”谁在写数据库”。后台导入器(工具 → 导入 → WordPress)解析的是 WXR(WordPress eXtended RSS)文件,走的是 WordPress Importer 插件的解析流程,中途会触发 wp_import_post_data 过滤器,适合站点之间的整站搬迁;WP All Import 面向的是结构化数据,把 CSV/XML 的列拖到字段上,靠 pmxi_saved_post 之类的动作钩子在保存后做二次处理;WP-CLI 与自写脚本则直接调用 wp_insert_post(),自由度最高,也最容易写错。
| 路径 | 适合场景 | 单次规模 | 学习成本 | 主要风险 |
|---|---|---|---|---|
| 后台导入器(WXR) | 整站迁移、换域名 | 几百篇 | 低 | 附件拉取超时、作者丢失 |
| WP All Import(CSV) | 表格化的产品/词条 | 几千行 | 中 | 编码错乱、字段映射错行 |
| WP-CLI / wp_insert_post | 程序化生成、定时同步 | 不限 | 高 | 需要自己兜住去重与性能 |
选型的判断标准很简单:数据已经在 Excel 里 → 用 WP All Import;数据在另一个 WordPress 站点 → 用导入器;数据来自外部接口或需要定时同步 → 写脚本挂 WP-Cron。别用脚本去干导入器能干的事,那是拿维护成本换一时的爽快。
保姆级实操
- 先把字段和模板定死,再谈导入
在 Excel 里建一张表,列头用英文:post_title、post_content、post_excerpt、post_status、post_date、category、tags、featured_image。先写 5 行样本跑通全流程,再铺开到几百行。这一步能暴露 80% 的字段问题,比导入完再返工便宜得多。
- 处理 CSV 编码与分隔符
Excel 默认导出的 CSV 是 GBK 或带 BOM 的 UTF-8,中文站导入后极易变成乱码或首列名被吞掉一个字符。用 VS Code 或 Notepad++ 转成 UTF-8 无 BOM,分隔符统一用逗号,字段里有换行的内容用双引号包裹。
- 用 WP All Import 做拖拽映射
新建导入任务(All Import → New Import),上传 CSV 后选择 Post Type 为 Posts。在 “Drag & Drop” 界面把左侧列拖到右侧对应字段:标题拖到 Title,正文拖到 Content,分类列拖到 Taxonomies → Categories。特色图片那一列填图片 URL,在 Images 区块勾选 “Download images hosted elsewhere”,插件会自动下载并生成 wp_generate_attachment_metadata() 需要的各尺寸缩略图。
- 用 WP-CLI 批量生成骨架文章
只想先铺出结构和占位内容、后续再逐篇精修时,WP-CLI 是最快的。先把分类建好,再批量生成:
# 先建分类(--slug 决定 URL,别让中文自动生成)
wp term create category "产品中心" --slug=products --porcelain
# 批量生成 60 篇草稿骨架,随机填充占位内容
wp post generate --count=60 --post_type=post --post_status=draft
# 按 CSV 逐行创建(标题用引号包裹,含空格必须加引号)
wp post create --post_type=post --post_title="A100 型液压阀技术参数" \
--post_status=draft --post_category=3 --porcelain
# 批量导入媒体库图片并自动附加到文章
wp media import ./images/*.jpg --post_id=123 --featured_image
- 用 PHP 脚本做带逻辑的写入
需要”按规则拼正文 + 关联分类 + 设特色图”时,直接写脚本。核心是 wp_insert_post() 返回文章 ID,再用 wp_set_object_terms() 挂分类、set_post_thumbnail() 设封面:
<?php
// 放在主题根目录或 mu-plugins 下,通过 WP-CLI 执行:wp eval-file import.php
require_once __DIR__ . '/../../../wp-load.php';
$rows = array_map( 'str_getcsv', file( __DIR__ . '/data.csv' ) );
array_shift( $rows ); // 去掉表头
foreach ( $rows as $row ) {
list( $title, $content, $cat_name, $img_url ) = $row;
// 用标题做幂等键,避免重复导入产生一堆 _1、_2 别名
if ( get_page_by_title( $title, OBJECT, 'post' ) ) {
continue;
}
$post_id = wp_insert_post( array(
'post_title' => sanitize_text_field( $title ),
'post_content' => wp_kses_post( $content ),
'post_status' => 'draft', // 先草稿,人工过一遍再 publish
'post_author' => 1,
'post_type' => 'post',
), true );
if ( is_wp_error( $post_id ) ) {
WP_CLI::log( '失败:' . $post_id->get_error_message() );
continue;
}
// 分类不存在就先建,再挂到文章上
$term = term_exists( $cat_name, 'category' );
if ( ! $term ) {
$term = wp_insert_term( $cat_name, 'category' );
}
wp_set_object_terms( $post_id, (int) $term['term_id'], 'category' );
// 远程图片下载 → 加入媒体库 → 设为特色图片
if ( $img_url ) {
$attach_id = media_sideload_image( $img_url, $post_id, $title, 'id' );
if ( ! is_wp_error( $attach_id ) ) {
set_post_thumbnail( $post_id, $attach_id );
}
}
}
- 导入后做三件质检
跑一次 wp post list --post_status=draft --fields=ID,post_title --format=table 核对数量;在后台文章列表按分类筛选,确认没有整批落到”未分类”;随机打开 10 篇看正文里的 HTML 标签有没有被转义成 <p>。
常见踩坑
- CSV 用 Excel 直接另存,中文全变问号:必须转 UTF-8 无 BOM,另存时选 “CSV UTF-8(逗号分隔)”。
wp_insert_post()返回 0 而不是 ID:通常是post_title、post_content为空,或post_type不存在,传第二个参数true让它返回 WP_Error 才能看到具体原因。- 案例:某站点用 WP All Import 一次导入 3000 行产品数据,导入到 1200 行时页面卡死重来,反复三次后数据库里堆了 3600 篇重复文章。原因是服务器
max_execution_time只有 30 秒,而插件默认一次跑完。正确做法是在 CSV 里先切分成每批 300 行,或用插件的 “Import in chunks” 设置分批执行。 - 特色图片 URL 是防盗链的外链图:下载会被 403 拒绝,导入后封面全空,应先下载到本地再批量上传。
- 导入后文章别名全是乱码百分号:中文标题自动生成的 slug 会变成一长串
%e4%ba%a7%e5%93%81,应提前在 CSV 里准备英文 slug 列,或用拼音 slug 与 URL 规划里讲的方案统一处理。 - 把
post_status直接设为 publish:几百篇未质检的内容一次性公开,收录了才发现正文有占位符,撤下来要重新等索引更新。 - 导入脚本忘了
wp_reset_postdata()或循环里套WP_Query:内存被吃光,报 “Allowed memory size exhausted”。
总结
内容填充的判断标准只有两条:能不能重跑而不产生重复数据,导入后能不能在 10 分钟内发现错误。前者靠幂等键(get_page_by_title() 或 CSV 里的唯一 ID 列),后者靠草稿态 + 抽样质检。规模小于 200 篇、数据在表格里,优先用 WP All Import;需要定时同步或拼接逻辑,再上 WP-CLI 脚本。填充完成后,配合 网站内容量与更新频率规划 安排后续节奏,别一次性把 90 天的内容全灌进去。图片相关的规范请对照 网站图片素材的规范与压缩流程,否则导入完还要返工压图。
