搜索全站
性能优化 11 分钟阅读

WP All Import 批量导入文章与图片:XML/CSV 映射配置全流程

从旧站或 ERP 导出的 XML/CSV 怎么进 WordPress?WP All Import 的拖拽映射能把任意结构映射到文章字段。本文讲清记录路径、唯一标识、图片下载与定时重跑的完整配置。

U
UFO_PF 2025-08-04 · 阅读 11 分钟
WP 性能优化
阅读提示
本文约 4,362 字,预计阅读 11 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:几千条数据靠手工复制是不现实的

迁移站、接 ERP、做采集站,都会碰到同一个问题:手上有几千条结构化数据(产品、房源、职位),要变成 WordPress 的文章,还要带上图片、分类和自定义字段。手工复制粘贴不现实,找人写一次性脚本则面临”下次数据更新怎么办”。

WP All Import 的定位就是这件事:给它一个 XML 或 CSV 文件,用鼠标把左边的源字段拖到右边的 WordPress 字段上,配好”怎么判断这条数据是否已经导入过”,剩下的交给它跑。免费版够做一次性导入;PRO 版支持从 URL 拉取文件、自动定时重跑、导入到自定义文章类型、导入图片到媒体库之外的更多目标(如 WooCommerce 变体)。

配套的导出插件(本站后面会单独讲)通常和它一起用,两者组合是同类站点之间搬数据的标准做法。

原理分析:三个必须先想清楚的概念

1. 记录路径(XPath / Root element)

XML 是一棵树,导入前必须告诉插件”哪一层节点是一条记录”。插件会让你在文件结构树里点选一个节点当记录根,选错会导致所有数据被塞进一篇文章。

2. 唯一标识符(Unique Identifier)

第二次导入时,插件靠什么判断”这条数据已有对应文章”?可选:文章标题、某个自定义字段(如 SKU)、文章 ID、Slug。选错会造成重复导入或覆盖错误。业务主键优先,没有就用标题。

3. 新增与更新的区分

「New Items」和「Existing Items」是两套独立策略:新增时可以决定默认状态、作者、分类;更新时可以决定”覆盖哪些字段””是否保留已有的特色图”。这两块配置分不清,是”导入一遍把已有内容冲掉”的头号原因。

配置项 作用 建议
Records per iteration 每次请求处理多少条 数据大时设 20–50,避免超时
Download images 是否把远程图片抓到媒体库 勾上,否则图片仍指向外站
Search Media Library first 是否先查重再上传 必须勾,否则重跑会重复上传
Delete posts not in file 文件里没有的条目是否删除 慎用,先备份
Update existing 是否更新已存在文章 按需,一般选”更新全部字段”

保姆级实操

第一步:准备源文件

一个典型的产品 XML 长这样:

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
    <product>
        <sku>AC-1001</sku>
        <name>工业离心风机</name>
        <desc><![CDATA[<p>风量 3000m³/h,适用车间排风。</p>]]></desc>
        <price>2800</price>
        <category>通风设备</category>
        <images>
            <image>https://cdn.example.com/AC-1001-1.jpg</image>
            <image>https://cdn.example.com/AC-1001-2.jpg</image>
        </images>
    </product>
</catalog>

CSV 则是首行为表头的文件(sku,name,desc,price,category)。CSV 不支持嵌套结构,图片多张时通常用分隔符串在一个单元格里。

第二步:上传文件并选记录根

「New Import → Upload a file」上传后,插件会展示结构树。把记录根选到 /catalog/product(即每一条 <product> 是一条记录),右侧会显示”共 N 条记录”。这一步务必核对数量与源文件一致。

第三步:选目标类型与唯一标识

Post Type 选 product(自定义文章类型需已在站点注册,参见 Custom Post Type UI 创建自定义文章类型),然后在「Existing Items」里把唯一标识设为 _sku 自定义字段。首次导入时全部是新增;第二次跑就会按 SKU 匹配更新。

第四步:拖拽映射

右边区域列出了所有可映射的目标:Title、Content、Excerpt、Featured Image、Images(图集)、Categories、Tags、Custom Fields。把左边的 {name[1]} 拖到 Title,{desc[1]} 拖到 Content,{sku[1]} 拖到 Custom Fields 里新建的 _sku。

字段值需要加工时,点右侧字段的「Function editor」,可以套用 PHP 函数:

[str_replace("元", "", {price[1]})]
[trim({name[1]})]

第五步:配置图片

把 {images/image[1]} 之类的节点拖到「Images」区域,并在下方勾选:

  • Download images hosted elsewhere:把外站图片抓到本站媒体库;
  • Search through the Media Library for existing images before uploading new media:先查重,重跑导入不会攒出一堆 image-1.jpg、image-2.jpg;
  • Set the first image to the Featured Image:第一张自动设为特色图。

第六步:用钩子补收尾逻辑

界面能做的有限,剩下的交给钩子:

// 每条数据导入后执行:$update 为 true 表示是更新而非新增
add_action( 'pmxi_saved_post', function ( $post_id, $xml_node, $update ) {
    $sku = (string) $xml_node->sku;
    update_post_meta( $post_id, '_sku', $sku );

    // 只在新增时自动发布,更新时保持原状态
    if ( ! $update ) {
        wp_update_post( array( 'ID' => $post_id, 'post_status' => 'publish' ) );
    }
}, 10, 3 );

// 整次导入结束后做一次汇总,可发邮件或写日志
add_action( 'pmxi_after_xml_import', function ( $import_id, $import ) {
    error_log( sprintf( 'import #%d finished, object=%s', $import_id, $import->options['custom_type'] ?? '' ) );
}, 10, 2 );

第七步:定时重跑

PRO 版的「Manage Imports → Scheduling」会给出一段 cron URL,把它交给服务器:

*/30 * * * * /usr/bin/wget -q -O - "https://mimangfei.com/wp-cron.php?import_key=XXXX&import_id=1&action=processing" >/dev/null 2>&1

如果你已经在系统 crontab 里接管了 WP-Cron,注意别让两套调度互相干扰,具体取舍见 WP-Cron 与系统 cron 配合配置。

常见踩坑

  1. 记录根选错。 选到 /catalog 会导致只生成一篇文章,内容全是第一条。每次上传后先看右侧记录条数。
  2. 唯一标识选了标题但源数据标题会变。 供应商改一次产品名,下次导入就新增一条重复数据。能用 SKU 就用 SKU。
  3. 没勾图片查重,重跑三次后媒体库多了两千张重复图。 磁盘和备份体积一起爆炸。
  4. desc 里是 HTML,导入后被转义成纯文本。 内容字段里若源是 HTML,确认没有套 strip_tags() 之类的函数,并检查 unfiltered_html 能力——权限不足时 <script>、<iframe> 会被过滤。
  5. 导入超时 502。 调小 Records per iteration,并把 PHP 的 max_execution_time 与内存调高;Nginx 侧同时放宽 fastcgi_read_timeout。
  6. 分类自动创建造成垃圾。 源文件里的分类名有错别字(”通风设备 “带空格),会生成两个同名不同 slug 的分类。导入前先清洗数据。
  7. 案例: 某外贸站每天从供应商 FTP 拉一次价格文件自动导入。某次供应商把 XML 的节点从 <product> 改成了 <item>,插件匹配不到记录根,导入结果”0 条记录”——但因为配置了”文件里没有的条目就删除”,插件直接把站上 1200 个产品全部删掉了。恢复靠的是前一天的完整备份。教训:开启”删除文件里没有的条目”之前,必须先有自动化备份,并且把删除阈值设保守。

总结

WP All Import 的使用要点是”先小后大”:先用只含 5 条记录的样本文件跑通全部映射,确认标题、正文、图片、分类、字段都对了,再换成全量文件。每次正式导入前保留一份数据库备份,尤其是要开删除策略时。

行动清单:核对记录条数 → 用业务主键做唯一标识 → 图片务必勾查重 → 用 pmxi_saved_post 补界面做不到的逻辑 → 定时重跑先手动验证一次再挂 cron。导入完成后若发现正文里的旧域名链接需要替换,接着做 批量替换文章内容 这一步。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。