You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于TypeScript实现GSC数据关联审计分数与流量异常检测

构建可扩展的SEO仪表盘(TypeScript方案)

需求概述

  • 合并Google Search Console(GSC)页面数据与审计分数(兼容URL格式差异)
  • 计算审计分数与点击量的Pearson相关系数,验证流量与分数的关联
  • 自动检测日展示量/点击量的统计显著性异常波动
  • 识别排名4-20的"Striking Distance"页面作为快速优化机会

已有数据样本

// GSC数据(来自Search Console API)
const gscPages = [
  { url: '/blog/react-seo', clicks: 1240, impressions: 18500, ctr: 0.067, position: 4.2 },
  { url: '/blog/meta-tags', clicks: 380, impressions: 9200, ctr: 0.041, position: 8.7 },
  { url: '/blog/seo-audit', clicks: 55, impressions: 3100, ctr: 0.018, position: 19.1 },
];

// 审计分数(来自审计工具)
const auditResults = [
  { url: '/blog/react-seo', score: 88, issues: [] },
  { url: '/blog/meta-tags', score: 71, issues: [] },
  { url: '/blog/seo-audit', score: 44, issues: [] },
];

// 日展示量时序数据
const dailyData = [
  { date: '2026-02-01', value: 8500 },
  { date: '2026-02-02', value: 8900 },
  { date: '2026-02-05', value: 24800 }, // 疑似峰值
  { date: '2026-02-07', value: 2100 },  // 疑似谷值
];

解决方案实现

1. 合并GSC数据与审计结果(处理URL格式差异)

先实现URL标准化逻辑,统一处理协议、域名、尾部斜杠等差异,再基于标准化后的URL合并数据集。

// URL标准化:去除协议、域名,统一尾部无斜杠
const normalizeUrl = (url: string): string => {
  const parsed = new URL(url.startsWith('http') ? url : `https://example.com${url}`);
  let path = parsed.pathname;
  if (path !== '/' && path.endsWith('/')) {
    path = path.slice(0, -1);
  }
  return path;
};

// 合并GSC数据与审计结果
const mergeSeoData = (gscData: typeof gscPages, auditData: typeof auditResults) => {
  const auditMap = new Map(auditData.map(item => [normalizeUrl(item.url), item]));
  
  return gscData.map(gscItem => {
    const normalizedUrl = normalizeUrl(gscItem.url);
    const auditItem = auditMap.get(normalizedUrl);
    return {
      ...gscItem,
      score: auditItem?.score ?? null,
      issues: auditItem?.issues ?? []
    };
  });
};

// 使用示例
const mergedData = mergeSeoData(gscPages, auditResults);

2. 计算Pearson相关系数(审计分数与点击量)

实现Pearson相关系数计算逻辑,同时筛选高潜力优化机会(排名4-20且审计分数较低的页面)。

// 计算Pearson相关系数
const calculatePearsonCorrelation = (mergedData: ReturnType<typeof mergeSeoData>) => {
  const validPoints = mergedData.filter(item => item.score !== null);
  
  if (validPoints.length < 2) return { correlation: 0, topOpportunities: [] };
  
  const n = validPoints.length;
  const sumX = validPoints.reduce((acc, item) => acc + item.score!, 0);
  const sumY = validPoints.reduce((acc, item) => acc + item.clicks, 0);
  const sumXY = validPoints.reduce((acc, item) => acc + (item.score! * item.clicks), 0);
  const sumX2 = validPoints.reduce((acc, item) => acc + (item.score! ** 2), 0);
  const sumY2 = validPoints.reduce((acc, item) => acc + (item.clicks ** 2), 0);
  
  // Pearson公式计算
  const numerator = n * sumXY - sumX * sumY;
  const denominator = Math.sqrt((n * sumX2 - sumX ** 2) * (n * sumY2 - sumY ** 2));
  const correlation = denominator === 0 ? 0 : numerator / denominator;
  
  // 筛选Top优化机会:排名4-20且分数低于70的页面,按展示量排序
  const topOpportunities = validPoints
    .filter(item => item.position >=4 && item.position <=20 && item.score! <70)
    .sort((a,b) => b.impressions - a.impressions)
    .slice(0,10);
  
  return { correlation: Number(correlation.toFixed(3)), topOpportunities };
};

// 使用示例
const correlationResult = calculatePearsonCorrelation(mergedData);

3. 时序数据异常检测(Z-score法)

基于Z-score统计量检测异常,超出±2倍标准差的数据视为统计显著异常。

// 检测时序数据异常
const detectAnomalies = (timeSeries: typeof dailyData, threshold = 2) => {
  const values = timeSeries.map(item => item.value);
  const n = values.length;
  
  if (n < 3) return [];
  
  // 计算均值和标准差
  const mean = values.reduce((acc, val) => acc + val, 0) / n;
  const variance = values.reduce((acc, val) => acc + (val - mean) **2, 0) / n;
  const stdDev = Math.sqrt(variance);
  
  // 筛选Z-score超出阈值的点
  return timeSeries.filter(item => {
    const zScore = Math.abs((item.value - mean) / stdDev);
    return zScore > threshold;
  });
};

// 使用示例
const anomalyResult = detectAnomalies(dailyData);

4. 识别"Striking Distance"页面与排名分桶

筛选排名4-20的页面,同时统计各排名区间的页面数量。

// 生成排名分桶与Striking Distance列表
const getRankingBuckets = (gscData: typeof gscPages) => {
  const buckets = [
    { range: '1-3', count: 0 },
    { range: '4-10', count: 0 },
    { range: '11-20', count: 0 },
    { range: '21+', count: 0 },
  ];
  
  const strikingDistance = gscData.filter(item => item.position >=4 && item.position <=20);
  
  // 统计各分桶数量
  gscData.forEach(item => {
    const pos = item.position;
    if (pos <=3) buckets[0].count++;
    else if (pos <=10) buckets[1].count++;
    else if (pos <=20) buckets[2].count++;
    else buckets[3].count++;
  });
  
  return { strikingDistance, rankingBuckets: buckets };
};

// 使用示例
const { strikingDistance, rankingBuckets } = getRankingBuckets(gscPages);

预期输出示例

相关系数与优化机会

{
  correlation: 0.741,
  topOpportunities: [
    { url: '/blog/seo-audit', clicks: 55, impressions: 3100, ctr: 0.018, position: 19.1, score: 44, issues: [] }
  ]
}

异常检测结果

[
  { date: '2026-02-05', value: 24800 }, // 峰值异常
  { date: '2026-02-07', value: 2100 }   // 谷值异常
]

排名分桶统计

[
  { range: '1-3', count: 0 },
  { range: '4-10', count: 2 },
  { range: '11-20', count: 1 },
  { range: '21+', count: 0 }
]

内容的提问来源于stack exchange,提问作者Al Amin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 21:17:28