本文约 4,567 字,预计阅读 12 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:手动推十条不如自动推一年
手动在资源平台粘贴 URL 提交,适合补漏,不可能长期坚持。真正省心的做法是——文章点”发布”的那一刻,程序自动把这条链接推给百度。百度主动推送接口本质上就是一个接受纯文本 body 的 HTTP POST 接口,用 PHP 实现不超过三十行。但要把这件事做稳,需要考虑几个工程细节:什么时候推(发布时还是更新时)、推送失败怎么办、如何避免草稿和私密内容被推、如何记录配额。本文给出一份可以直接放进主题的 PHP 实现,同时说明它与插件方案的取舍。
原理分析:接口与触发时机
主动推送接口的地址是 http://data.zz.baidu.com/urls,参数是 site(验证过的完整域名)和 token(入口页提供的密钥),请求体是每行一个 URL 的纯文本,Content-Type 必须是 text/plain。返回值为 JSON,包含 success(成功条数)、remain(剩余配额)、not_same_site(不属于本站的 URL)、not_valid(不合法的 URL)。
触发时机的选择是关键。WordPress 里常见三个钩子:publish_post(状态转为 publish 时触发,更新也会触发)、transition_post_status(状态流转,可精确判断”首次发布”)、save_post(保存即触发,太频繁)。推荐用 transition_post_status 判断 $new_status === 'publish' && $old_status !== 'publish',只推首次发布,避免每次改错别字都消耗配额。另外要排除:post_status 非 public 的类型、密码保护文章、noindex 的文章。
保姆级实操
第一步:拿到 token
登录 ziyuan.baidu.com → 资源提交 → 普通收录 → API 提交,页面会给出 token=xxxxxx 及示例接口地址,复制备用。
第二步:封装推送函数
把下面代码放进主题 functions.php(推荐放到子主题,避免主题升级被覆盖):
<?php
// 百度主动推送:纯 PHP 实现,放子主题 functions.php
function mimangfei_baidu_push( array $urls, string $type = '' ): array {
$site = 'https://mimangfei.com'; // 必须与验证站点完全一致
$token = '你的推送token'; // 从资源平台 API 提交页获取
if ( empty( $urls ) ) {
return array( 'ok' => false, 'msg' => 'urls empty' );
}
// 去空、去重、限制单次条数
$urls = array_values( array_unique( array_filter( array_map( 'trim', $urls ) ) ) );
$urls = array_slice( $urls, 0, 50 );
$api = 'http://data.zz.baidu.com/urls?site=' . rawurlencode( $site )
. '&token=' . rawurlencode( $token );
if ( 'realtime' === $type ) { // 快速收录
$api .= '&type=realtime';
}
$args = array(
'timeout' => 5,
'blocking' => true,
'headers' => array( 'Content-Type' => 'text/plain' ),
'body' => implode( "\n", $urls ),
'redirection' => 0,
);
$resp = wp_remote_post( $api, $args );
if ( is_wp_error( $resp ) ) {
error_log( '[baidu-push] request failed: ' . $resp->get_error_message() );
return array( 'ok' => false, 'msg' => $resp->get_error_message() );
}
$code = wp_remote_retrieve_response_code( $resp );
$body = json_decode( wp_remote_retrieve_body( $resp ), true );
if ( 200 === $code && isset( $body['success'] ) ) {
// 记录剩余配额,便于观察趋势
update_option( 'mimangfei_baidu_remain', intval( $body['remain'] ) );
update_option( 'mimangfei_baidu_remain_at', current_time( 'mysql' ) );
return array( 'ok' => true, 'data' => $body );
}
// 失败写入日志,方便排查 token / 站点不匹配
error_log( '[baidu-push] code=' . $code . ' body=' . wp_remote_retrieve_body( $resp ) );
return array( 'ok' => false, 'msg' => wp_remote_retrieve_body( $resp ) );
}
第三步:挂载首次发布钩子
add_action( 'transition_post_status', function ( $new_status, $old_status, $post ) {
// 只在"首次发布"时触发,避免更新消耗配额
if ( 'publish' !== $new_status || 'publish' === $old_status ) {
return;
}
if ( 'post' !== $post->post_type || post_password_required( $post ) ) {
return;
}
$ret = mimangfei_baidu_push( array( get_permalink( $post ) ) );
// 失败时排进计划任务,30 分钟后重试一次
if ( empty( $ret['ok'] ) ) {
wp_schedule_single_event( time() + 1800, 'mimangfei_baidu_retry', array( $post->ID ) );
}
}, 10, 3 );
add_action( 'mimangfei_baidu_retry', function ( $post_id ) {
$url = get_permalink( $post_id );
if ( $url ) {
mimangfei_baidu_push( array( $url ) );
}
} );
第四步:加一个后台入口,补推历史文章(历史量很大时,也可以配合百度sitemap提交的多种方式让百度批量发现)
在 wp-admin 加一个按钮,把最近 30 天未推送的文章批量提交。批量时务必分批(每批 50 条)并加 sleep,避免打满配额。
第五步:验证
发布一篇测试文章后,查看接口返回值(可在 wp-content/debug.log 里看到失败日志),并在资源平台「资源提交 → API 提交」页看累计提交量是否增加。
第六步:与插件方案对比
插件方案(如各类 SEO 插件自带的推送模块)优点是零代码、带界面,缺点是推送时机固定、难以与自己的发布流程(如定时发布、API 发文)配合,且主题切换后配置可能丢失。代码方案的优点是可控、能接进自己的发布系统,缺点是要自己维护。如果你有自动化发文流程,代码方案更合适。
常见踩坑
site参数漏写协议或写成 www/裸域不一致:必须与站点管理中验证的域名逐字符一致。Content-Type用了application/x-www-form-urlencoded:接口只接受text/plain,否则返回 400。- 用
save_post触发导致草稿反复推送:草稿的 permalink 可能带?p=123形式,推送无效 URL 还会占配额。 - 同步请求拖慢发布:一定要设
timeout,失败时排异步重试,不要让发布按钮转圈。 - 案例:某站点把推送代码挂在
save_post上,编辑每按一次”更新”就推一次,一个月把配额耗光,真正的新文章反而推不出去。改成transition_post_status判断首次发布后,配额消耗降到原来的十分之一。 - HTTPS 站点推送 http 链接:会被判为不同 URL,最终收录的是另一个版本,造成重复。
- 忽略
not_valid返回:接口返回 200 不代表全部成功,要解析 JSON 里的not_valid数组。
总结
判断标准:主动推送只需要满足三件事——首次发布时触发、URL 与验证站点严格一致、失败可重试且不影响发布体验。行动清单:拿 token → 放 PHP 推送函数 → 挂 transition_post_status → 排除密码保护与非公开类型 → 记录 remain 趋势 → 每月检查失败日志。如果你暂时不想写代码,可以先用百度自动推送JS安装这种零代码方案过渡,两者并不冲突,可以同时开。
