WP Search Analytics-搜索关键词统计与分析插件

WP Search Analytics:站内搜索关键词统计与分析插件

本文对应插件版本 v1.4.0(2026-08 更新)。相较最初发布的 v1.0.1,插件新增了最新搜索记录、IP 归属地、搜索结果自定义 HTML 注入、独立设置页与更新日志页,并对后台 UI 做了两轮重构。文末附「与旧版文章的差异对照」,老读者可直接跳到第八节。

一、插件简介

WP Search Analytics 是一款专为 WordPress 网站设计的搜索关键词统计与分析插件。它能帮助网站管理员深入了解访客的搜索行为,通过直观的数据可视化、详细的搜索词记录和强大的分析功能,轻松掌握用户最关心的内容,从而优化网站内容策略,提升用户体验。

插件基于 WordPress 标准开发规范构建,轻量、高效,与绝大多数主题和插件兼容,无需修改主题文件即可自动追踪所有原生搜索请求。

从 v1.1.0 开始,插件不再只是“统计工具”,而是加入了运营干预能力:当访客搜不到内容时,可以自动在搜索结果页下方插入你预设的 HTML(推荐文章、客服入口、引导表单等),把无效搜索转化为有效停留。

WP Search Analytics 仪表盘界面

WP Search Analytics 热门搜索排行界面

WP Search Analytics 最新搜索记录界面


二、主要功能

1. 全面的搜索数据统计

  • 总搜索次数:记录全站所有搜索请求的总次数。
  • 唯一搜索词:按关键词哈希去重统计,反映用户需求的广度。
  • 今日搜索量:实时展示当天的搜索活跃度,方便监控突发流量。
  • 今日独立 IP 数:判断搜索量是“多人少搜”还是“一人狂搜”。
  • 今日无结果搜索数:直接暴露内容缺口,是选题的第一手素材。

2. 趋势图表分析

  • 可视化趋势图:使用 Chart.js 绘制搜索量随时间变化的折线图(indigo 配色,带面积填充)。
  • 多时间维度:支持按 7天 / 30天 / 90天 / 1年 快速切换,服务端对天数做白名单校验(仅接受 7/30/90/365)。

3. 热门搜索词排行(独立页面)

自 v1.3.0 起,热门搜索词从仪表盘中分离为独立页面 搜索分析 → 热门搜索

  • 按搜索次数排序,默认展示前 100 个关键词。
  • 排名徽章:Top 3 使用金/银/铜渐变背景 + 阴影,其余为统一灰色。
  • 动画进度条:以第一名为基准计算百分比,进度条带 shimmer 光效。
  • 平均结果数:展示该关键词历次搜索的平均命中数量。
  • 状态标签:平均结果 > 0 显示“有结果”,否则显示“无结果”(带圆点指示器)。
  • 最后搜索时间:相对时间显示(如“3 小时前”),鼠标悬停显示完整时间。
  • 关键词筛选:输入框带 350ms 防抖,AJAX 实时过滤。
  • 一键刷新:按钮图标旋转动画,重新拉取数据。

4. 最新搜索记录(独立页面)

自 v1.2.0 起新增 搜索分析 → 最新搜索 页面,默认展示最近 50 条明细记录:

说明
# 序号
搜索关键词 indigo 浅色 pill 标签
搜索时间 相对时间 + 时钟图标,hover 显示完整时间戳
IP 地址 等宽 code 样式
归属地 国家 + 省份 + 城市,琥珀色渐变标签 + 定位图标
浏览器 / 系统 彩色徽章,Chrome 蓝、Firefox 橙、Safari 蓝、Edge 绿、Opera 红等
结果数 0 为红色 pill,非 0 为绿色 pill

筛选范围覆盖关键词、IP、国家、省份、城市五个字段,输入任意片段即可定位。

5. 搜索结果自定义 HTML 注入

这是 v1.1.0 引入的核心运营功能,在 搜索分析 → 设置 中配置:

  • 启用开关:默认关闭。
  • 结果数量阈值:当 found_posts <= 阈值 时触发注入。设为 0 表示仅在完全无结果时显示;设为 3 则结果少于等于 3 条时也会显示。
  • 自定义 HTML 内容:支持任意 HTML 标签,输出时包裹在 <div class="wpsa-custom-html"> 中,便于主题自定义样式。

注入采用三重钩子保障,兼容各种主题写法:

  1. loop_end —— 有结果时在循环结束后输出;
  2. loop_no_results —— 无结果时输出(WordPress 6.2+);
  3. wp_footer —— 兜底输出,确保前两个钩子都未触发时内容仍能显示。

内部通过 $_html_injected 标志位保证同一次请求只输出一次,不会重复。

6. IP 归属地识别

  • 通过 ip-api.com 免费接口查询,请求参数已指定 lang=zh-CN,返回中文地名。
  • 结果写入 transient 缓存,有效期 7 天,同一 IP 不重复请求。
  • 私有/保留地址(内网 IP、127.0.0.1 等)直接标记为「本地网络」,不发起外部请求。
  • 支持在设置页一键关闭;关闭后不再查询新 IP,已有数据保留。
  • IP 获取顺序为 HTTP_CLIENT_IPHTTP_X_FORWARDED_FOR(取最左侧原始客户端)→ REMOTE_ADDR,并用 filter_var 做合法性校验。

7. 数据管理工具

  • 导出 CSV:一键导出全部关键词统计(关键词、搜索次数、平均结果数、最后搜索时间)。文件带 UTF-8 BOM,Excel 打开不乱码,文件名自动附加日期。
  • 清理数据:可自定义天数(如 90 天)删除旧记录,主表与日汇总表同步清理;输入 0TRUNCATE 两张表清空全部数据。操作前有 JS 二次确认。

8. 仪表盘小工具与更新日志

  • 后台仪表盘小工具:在 WordPress 首页概览「总搜索 / 唯一词 / 今日」三项核心指标,并提供「查看完整报告 →」跳转链接。
  • 更新日志页面搜索分析 → 更新日志,内置从 1.0.1 到 1.4.0 的完整版本记录,升级后无需查文档即可知道改了什么。

三、后台菜单与配置项

1. 菜单结构

激活后,后台左侧出现顶级菜单「搜索分析」(dashicons-search 图标,位置 30),包含 5 个子页面:

子页面 slug 说明
仪表盘 wpsa-dashboard 核心指标卡片 + 趋势图 + 快捷入口
热门搜索 wpsa-popular 关键词排行榜(Top 100)
最新搜索 wpsa-latest-searches 最近 50 条明细记录
设置 wpsa-settings 自定义 HTML、IP 归属地、数据清理、CSV 导出
更新日志 wpsa-changelog 版本变更记录

全部页面均要求 manage_options 权限。

2. 配置项一览

所有设置存储在单个 option wpsa_settings(数组形式):

配置键 类型 默认值 说明
enable_custom_html int (0/1) 0 是否启用搜索结果自定义内容注入
result_threshold int 0 结果数 ≤ 该值时注入,0 = 仅无结果时
custom_html string '' 注入的 HTML 内容
enable_ip_geolocation int (0/1) 1 是否启用 IP 归属地查询

另有独立 option wpsa_version 记录当前已安装版本号,用于升级时触发数据库迁移。


四、技术架构概览

1. 文件目录结构

wp-search-analytics/
├── wp-search-analytics.php          # 主插件文件(常量、激活钩子、类加载、版本迁移)
├── uninstall.php                    # 卸载时删表 + 清理 option 与 transient
├── readme.txt                       # WordPress 标准 readme
├── includes/
│   ├── class-database.php           # 数据库操作(建表、迁移、写入、统计查询、清理、导出)
│   ├── class-search-tracker.php     # 搜索追踪 + IP 归属地 + 自定义 HTML 注入
│   ├── class-admin.php              # 菜单、资源加载、页面渲染、设置/清理/导出处理
│   └── class-ajax-handler.php       # AJAX 接口(趋势、热门词、最新记录)
├── templates/
│   ├── admin-page.php               # 仪表盘模板
│   ├── popular-searches.php         # 热门搜索词页面模板(服务端渲染)
│   └── latest-searches.php          # 最新搜索记录页面模板(服务端渲染)
└── assets/
    ├── css/
    │   └── admin.css                # 后台样式(约 890 行,CSS 变量配色体系)
    └── js/
        └── admin.js                 # 后台脚本(Chart.js 图表 + 两个页面的筛选/刷新)

可选:将 chart.min.js 放入 assets/js/ 目录,插件会自动优先加载本地版本,不再请求 CDN。

2. 核心类设计

类名 职责 关键方法
WPSA_Database 数据库操作 create_tables()maybe_migrate()table_exists()insert_search()get_total_searches()get_unique_terms_count()get_today_searches()get_today_unique_ips()get_today_no_result_searches()get_trend_data()get_popular_terms()get_latest_searches()clean_old_data()export_all_data()
WPSA_Search_Tracker 搜索追踪与前台注入 track_on_wp()track_ajax_search()get_user_ip()get_ip_location()maybe_inject_custom_html()inject_custom_html()inject_custom_html_footer()
WPSA_Admin 后台界面与工具 add_admin_menu()enqueue_assets()add_dashboard_widget()render_dashboard()render_popular()render_latest_searches()render_settings()render_changelog()handle_save_settings()handle_clean_old_data()handle_export_csv()
WPSA_Ajax_Handler AJAX 接口 get_trend_data()get_popular_terms()get_latest_searches()

3. 数据库设计

采用两张表,以平衡实时写入和查询性能。

主表 wp_search_analytics

存储每一条搜索记录,用于明细查询和统计。

字段 类型 说明
id BIGINT 自增主键
search_term VARCHAR(255) 用户输入的关键词(超长自动截断)
search_term_hash VARCHAR(64) 关键词 SHA-256 哈希,用于去重统计
result_count INT 搜索结果数量(0 表示无结果)
user_id BIGINT 用户 ID(0 为访客)
user_ip VARCHAR(45) 用户 IP,兼容 IPv6
ip_country VARCHAR(100) v1.1.0 新增 国家
ip_region VARCHAR(100) v1.1.0 新增 省/州
ip_city VARCHAR(100) v1.1.0 新增 城市
user_agent TEXT 浏览器 UA
referer VARCHAR(500) 来源页面
search_date DATETIME 搜索时间(WordPress 时区)

索引search_term_hashsearch_dateresult_count

汇总表 wp_search_analytics_daily

按「关键词 + 日期」聚合。

字段 类型 说明
id BIGINT 自增主键
search_term VARCHAR(255) 关键词原文
search_term_hash VARCHAR(64) 哈希
search_date DATE 统计日期
total_searches INT 当日搜索次数
total_results INT 当日结果总数(用于算平均)
last_search_time DATETIME 当日最后一次搜索时间

唯一索引(search_term_hash, search_date)。写入采用 INSERT ... ON DUPLICATE KEY UPDATE 原子操作,高并发下不会出现竞态导致的计数丢失。

数据库迁移

dbDelta() 在部分环境下不会为已存在的表补充新列,因此 v1.3.1 起增加了 maybe_migrate():通过 DESCRIBE 读取现有列,逐一比对 ip_countryip_regionip_city,缺失则 ALTER TABLE ADD COLUMN

迁移触发时机有两处:插件激活时,以及每次 plugins_loaded 时对比 wpsa_versionWPSA_VERSION,版本落后即自动执行。也就是说,通过 FTP 直接覆盖文件升级也能正确迁移,无需重新激活插件。

4. 关键钩子与流程

搜索追踪

  1. 原生搜索:监听 wp 钩子,判断 is_search() && ! is_admin(),取 get_search_query( false )$wp_query->found_posts,随后采集 IP、归属地、UA、referer 一并写库。
  2. AJAX 搜索:主题若使用 AJAX 搜索,可调用 wpsa_track_ajax_search 接口(同时注册了 wp_ajax_wp_ajax_nopriv_),POST 传 search_termresult_countnonce

前台 AJAX 上报示例:

jQuery.post( ajaxurl, {
    action: 'wpsa_track_ajax_search',
    search_term: '关键词',
    result_count: 12,
    nonce: wpsa_nonce   // 由 wp_create_nonce('wpsa_nonce') 生成
} );

注意:前台页面需自行用 wp_localize_script() 输出 wpsa_nonce,插件本身只在后台注入 wpsa_ajax 对象。

管理界面数据加载

v1.3.2 起改为 PHP 服务端渲染优先:热门搜索、最新搜索两个页面在 PHP 渲染阶段就把数据写进表格,页面加载完即可见数据,不再出现 AJAX 失败导致的“正在加载…”卡死。AJAX 仅用于后续的筛选与刷新。

模板底部还内嵌了一段回退脚本:

<script type="text/javascript">
if ( typeof wpsa_ajax === 'undefined' ) {
    var wpsa_ajax = {
        ajax_url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
        nonce: '<?php echo wp_create_nonce( 'wpsa_nonce' ); ?>'
    };
}
</script>

用于兜底 wp_localize_script() 在某些环境下失效的情况。admin.js 开头也会检查 wpsa_ajax 是否存在,不存在则打印警告并安全退出,不会抛异常。

AJAX 接口一览

action 权限 参数 说明
wpsa_get_trend_data manage_options days(7/30/90/365)、nonce 趋势数据
wpsa_get_popular_terms manage_options limitsearchnonce 热门关键词
wpsa_get_latest_searches manage_options limit(1-100)、searchnonce 最新记录
wpsa_track_ajax_search 公开(需 nonce) search_termresult_countnonce 前台搜索上报

表单类操作走 admin-post.phpwpsa_save_settingswpsa_clean_old_datawpsa_export_csv,各自使用独立 nonce(wpsa_settings_noncewpsa_clean_noncewpsa_export_nonce)。

5. 资源加载策略

这一块在 v1.3.0 / v1.3.1 连续修过两个坑,值得单独说明:

  • 按页面加载:只在 wpsa-* 五个页面和 WordPress 首页仪表盘(index.php)加载 CSS/JS,不污染其他后台页面。
  • 通过 $_GET['page'] 判断而非 $hook:因为菜单标题是中文,$hook 会带上编码后的乱码字符串,早期版本据此判断导致子页面样式完全不加载。
  • Chart.js 按需加载:仅仪表盘页面加载 Chart.js。其他页面的 admin.js 只依赖 jQuery——早期把 Chart.js 写成硬依赖,CDN 一旦被墙,热门搜索/最新搜索页面的 JS 直接不执行。
  • 本地优先:若存在 assets/js/chart.min.js 则加载本地文件,否则回退到 cdn.jsdelivr.net

6. 安全与性能

  • 权限控制:所有后台功能与管理类 AJAX 均校验 manage_options
  • Nonce 校验:所有 AJAX 与表单提交均带 nonce,防 CSRF。
  • SQL 注入防护:全部动态查询使用 $wpdb->prepare(),LIKE 查询经 $wpdb->esc_like() 转义。
  • 输出转义:模板中用户数据统一 esc_html() / esc_attr() 处理。
  • 表存在性检查:所有统计方法先调 table_exists(),表不存在返回 0 或空数组,避免建表失败时后台白屏报错。
  • 哈希索引:以 search_term_hash 做去重依据,规避长文本字段索引的性能问题。
  • 归属地缓存transient 缓存 7 天,同一 IP 只查一次外部接口。
  • 时区统一:所有时间写入与比较均使用 current_time(),跟随 WordPress 后台设定的时区,不受服务器时区影响。

7. 兼容性与依赖

  • WordPress:5.0 及以上(loop_no_results 钩子需 6.2+,无该钩子时由 wp_footer 兜底),已测试至 6.5。
  • PHP:7.4 及以上(代码使用了 ?? 运算符)。
  • JavaScript:Chart.js v4.4.0(本地或 CDN)+ jQuery(WordPress 内置)。
  • 数据库:MySQL 5.7+ / MariaDB 10.2+,需支持 INSERT ... ON DUPLICATE KEY UPDATE
  • 界面语言:后台文案为简体中文,已包裹 __() / _e(),Text Domain 为 wp-search-analytics

五、数据流程图

WP Search Analytics 数据流程图


六、安装、升级与使用

1. 全新安装

  1. 上传:后台「插件 → 安装插件 → 上传插件」选择 zip 包,或通过 FTP 将 wp-search-analytics 文件夹上传至 /wp-content/plugins/
  2. 激活:激活时自动建表并写入默认设置,无需手动操作。
  3. 验证:在前台随便搜索一个词,然后进入「搜索分析 → 最新搜索」,应能看到刚才那条记录。

2. 从旧版本升级

直接覆盖文件即可。plugins_loaded 时会比对版本号,自动执行建表与列迁移。从 1.0.x / 1.1.x 升级的用户请务必刷新一次后台,让 ip_country 等新列补齐,否则最新搜索页的归属地列会一直为空。

3. 日常使用建议

  • 看内容缺口:优先关注「今日无结果搜索」和热门搜索里状态为“无结果”的关键词——这些是用户想要但你没有的内容,是最直接的选题来源。
  • 配自定义 HTML:把无结果页变成引导页。示例:
<div style="padding:20px;background:#f8fafc;border-radius:8px;margin-top:20px;">
  <h3>没找到想要的内容?</h3>
  <p>试试这些热门文章:</p>
  <ul>
    <li><a href="/archives/">全部文章归档</a></li>
    <li><a href="/categories/">按分类浏览</a></li>
  </ul>
  <p>或者 <a href="/contact/">直接联系我们</a>,告诉我们你想看什么。</p>
</div>

保存后在前台搜索一个不存在的词验证效果。

  • 定期维护:建议每季度在设置页清理一次 90 天前的旧数据;清理前可先导出 CSV 存档。
  • CSV 用法:导出的文件带 BOM,双击直接用 Excel 打开即可,可用于制作月度搜索报表。

七、注意事项与已知限制

这些是实际使用中容易踩的点,提前说清楚:

  1. 搜索分页会重复计数。追踪挂在 wp 钩子上,用户翻到搜索结果第 2 页会再记一条。如果你的站点搜索结果经常分页,总搜索次数会略高于真实搜索行为数。
  2. 管理员和爬虫的搜索也会被记录。插件不区分角色和 UA,自己测试搜索同样入库。介意的话可以在清理时按天数处理,或后续自行加过滤。
  3. IP 归属地查询是同步阻塞的。首次遇到新 IP 时会发起一次 HTTP 请求(超时 3 秒),极端情况下会让搜索页响应变慢。命中缓存后无此开销。对速度敏感的站点可在设置中关闭该功能。
  4. ip-api.com 免费版有频率限制(约 45 次/分钟)且为 HTTP 明文接口。高流量站点建议关闭,或自行替换为付费/自建服务。
  5. 自定义 HTML 不做过滤,会原样输出。这是刻意设计(否则 <script>、内联样式都会被剥掉),但意味着只应由可信管理员填写。多作者站点请注意 manage_options 权限的分配。
  6. Chart.js 默认走 CDN。插件包内不含 chart.min.js,如果 cdn.jsdelivr.net 访问不畅,仪表盘趋势图会空白(其他页面不受影响,因为已解除硬依赖)。解决办法:下载 Chart.js v4.4.0 放到 assets/js/chart.min.js,插件会自动优先使用本地文件。
  7. 日汇总表目前只写不读。趋势图和热门词排行仍然直接查询主表。汇总表数据是完整且准确的,为后续大数据量优化预留——数据量超过百万级时改查汇总表即可获得明显提速。
  8. 卸载会删除全部数据uninstall.php 会 DROP 两张表、删除 wpsa_versionwpsa_settings,并清理所有 wpsa_ip_ 前缀的 transient。仅“停用”不会删数据,“删除”才会。重要数据请先导出。

八、与旧版文章(v1.0.1)的差异对照

如果你看过本文最初的版本,以下是这段时间的实际变化:

项目 旧文所述(v1.0.1) 当前实际(v1.4.0)
版本号 1.0.1 1.4.0
后台菜单 仅仪表盘 仪表盘 / 热门搜索 / 最新搜索 / 设置 / 更新日志 五个页面
配置项 “无需配置,开箱即用” 新增设置页,含 4 项配置(wpsa_settings
主表字段 9 个字段 新增 ip_countryip_regionip_city 三列
数据清理 “汇总表暂不清理,未来可扩展” 已实现主表与汇总表同步清理,并支持传 0 清空全部
明细记录 最新搜索页,50 条明细含 IP、归属地、浏览器、系统
运营干预 搜索结果自定义 HTML 注入(三重钩子)
统计维度 3 项 新增今日独立 IP、今日无结果搜索
数据加载 全部 AJAX 异步 改为 PHP 服务端渲染优先,AJAX 仅负责筛选与刷新
Chart.js 全局依赖 仅仪表盘加载,本地文件优先、CDN 回退
数据库升级 依赖 dbDelta 新增 maybe_migrate() 列级迁移 + 版本号自动检测
写入并发 普通更新 日汇总改为 INSERT ... ON DUPLICATE KEY UPDATE 原子操作
时区 未处理 统一使用 current_time(),跟随 WP 设置
卸载清理 仅删表 删表 + 删 option + 清理 IP 缓存 transient
UI 基础 WP 后台样式 渐变 banner、玻璃质感卡片、彩色徽章、动画进度条,CSS 变量配色体系

九、后续规划

  • 汇总表投入查询:数据量大时切换趋势图与排行榜的数据源,进一步降低查询开销。
  • 异步写入:将追踪写入改为 wp_schedule_single_event,彻底消除对前台响应时间的影响。
  • 扩展钩子:在 track_on_wp() 中加入 do_action,方便第三方插件挂接自定义逻辑。
  • 隐私增强:增加 IP 匿名化选项(如只保留前三段),满足 GDPR 场景。
  • 角色/爬虫过滤:可配置是否记录登录用户、指定角色或已知爬虫 UA 的搜索。
  • 本地化 IP 库:内置离线 IP 库选项,摆脱对外部接口的依赖。

十、总结

WP Search Analytics 从最初的“记录 + 图表”工具,逐步演进为一套完整的站内搜索运营方案:看得见数据(明细、归属地、设备)、看得懂问题(无结果搜索、内容缺口)、能立刻干预(自定义 HTML 注入)。

v1.3.x 的几次修复解决了数据不显示这类致命问题,v1.4.0 则把后台界面推到了可以拿出手的水准。对个人博客来说它足够轻;对企业站点来说,哈希索引、原子写入、日汇总表这些设计也留足了扩容余地。

如果您有任何定制需求或建议,欢迎与我们联系,我们将持续迭代优化。

下载地址
夸克
wp-search-analytics.zip
密码:无
上一篇 AeroCore Free 主题文章默认图片居中
下一篇 Auto MD5 Slug自动将中文别名转换为 MD5 哈希,告别冗长 URL 编码