做营销投放的人都知道一个痛:广告链接上线后,UTM参数莫名其妙就丢了。花了钱投出去的广告,流量归因直接变成"direct",预算打了水漂还不知道哪里出了问题。
手动一条条点开链接去检查?几十条营销链接,每个都要看最终URL里UTM参数在不在,这不现实。今天分享3个用curl批量验证营销链接参数保留的实战脚本方案,帮你一次性搞定几百条营销链接的参数检查。
一、为什么营销链接参数会丢?
在动手写脚本之前,先搞清楚参数丢失的常见原因,这样才能对症下药:
- HTTP跳HTTPS时参数被剥离:Nginx用
return 301 https://$host$request_uri;但重定向目标没拼上$is_args$args - 短链服务拼接UTM参数位置错误:UTM放在锚点
#后面,浏览器不会把锚点后的内容发送到服务器 - CDN层重定向清空查询字符串:Cloudflare等CDN的Transform Rules没有配置参数透传
- 多次重定向中某一跳把参数吃掉了:A跳B保留参数,B跳C却用
?结尾把参数清空
这些问题的排查核心就是:用curl模拟完整的重定向链路,检查最终URL里UTM参数还在不在。
二、方案一:基础版——逐条检测UTM参数是否保留
最直接的方法:从文件里读取营销链接列表,对每条链接用curl -L -s跟随重定向,然后用-w参数输出最终的url_effective,检查里面有没有UTM参数。
脚本代码
#!/bin/bash
# 营销链接UTM参数批量检测脚本(基础版)
URL_FILE="marketing_links.txt"
RESULT_FILE="param_check_result.csv"
PARAM_PATTERN="utm_source|utm_medium|utm_campaign"
echo "原始链接,最终URL,状态" > "$RESULT_FILE"
while IFS= read -r url; do
# 跳过空行和注释
[[ -z "$url" || "$url" =~ ^# ]] && continue
# 获取最终跳转后的URL
final_url=$(curl -L -s -o /dev/null -w '%{url_effective}' --max-time 10 "$url")
# 检查UTM参数是否保留
if echo "$final_url" | grep -qiE "$PARAM_PATTERN"; then
status="✓ 参数保留"
else
status="✗ 参数丢失"
fi
echo "\"$url\",\"$final_url\",\"$status\"" >> "$RESULT_FILE"
echo "$status: $url"
done < "$URL_FILE"
echo "检测完成,结果已保存到 $RESULT_FILE"
输入文件格式
创建marketing_links.txt,每行一条链接:
https://example.com/promo?utm_source=wechat&utm_medium=cpc&utm_campaign=summer
https://short.link/abc123?utm_source=douyin&utm_medium=feed
https://landing.example.com/?utm_source=baidu&utm_medium=sem&utm_campaign=brand
这个脚本的优点
- 逻辑简单,容易理解和修改
- 直接输出CSV格式,可以用Excel打开查看
--max-time 10设置超时,避免卡死在某个链接上
三、方案二:进阶版——多渠道分组检测+差异对比
营销链接通常来自不同渠道(微信、抖音、百度、小红书等),每个渠道的链接结构可能不同。进阶版脚本会把链接按渠道分组,统计每个渠道的参数保留率,快速定位哪个渠道出了问题。
脚本代码
#!/bin/bash
# 营销链接UTM参数批量检测脚本(进阶版-渠道分组)
URL_FILE="marketing_links.txt"
REPORT_FILE="channel_report.txt"
declare -A channel_total
declare -A channel_pass
while IFS='|' read -r channel url; do
[[ -z "$url" || "$url" =~ ^# ]] && continue
channel_total["$channel"]=$((${channel_total["$channel"]:-0} + 1))
final_url=$(curl -L -s -o /dev/null -w '%{url_effective}' --max-time 10 "$url")
if echo "$final_url" | grep -qiE "utm_source|utm_medium"; then
channel_pass["$channel"]=$((${channel_pass["$channel"]:-0} + 1))
result="✓"
else
result="✗ 丢失 → $final_url"
fi
echo "[$channel] $result $url"
done < "$URL_FILE"
# 生成渠道汇总报告
{
echo "================================"
echo " 营销链接参数保留渠道汇总报告"
echo "================================"
printf "%-15s %8s %8s %10s\n" "渠道" "总数" "通过" "保留率"
echo "--------------------------------"
for ch in "${!channel_total[@]}"; do
total=${channel_total[$ch]}
pass=${channel_pass[$ch]:-0}
rate=$((pass * 100 / total))
printf "%-15s %8d %8d %9d%%\n" "$ch" "$total" "$pass" "$rate"
done
} > "$REPORT_FILE"
cat "$REPORT_FILE"
echo "报告已保存到 $REPORT_FILE"
输入文件格式(渠道|链接)
wechat|https://example.com/wx?utm_source=wechat&utm_medium=cpc&utm_campaign=sum
douyin|https://short.link/abc?utm_source=douyin&utm_medium=feed
baidu|https://landing.example.com/?utm_source=baidu&utm_medium=sem
这个方案的核心价值在于渠道维度的保留率统计。如果微信渠道保留率99%、抖音渠道只有60%,你就知道该去查抖音短链服务的配置了。
四、方案三:自动化巡检版——定时检测+异常告警
真正的生产环境里,不能每次手动跑脚本。把检测脚本挂到crontab上,每天自动跑一次,发现参数丢失的链接立刻发钉钉/邮件告警。
核心检测逻辑
#!/bin/bash
# 营销链接UTM自动巡检脚本
URL_FILE="/data/marketing/links.txt"
LOG_FILE="/data/marketing/check_$(date +%Y%m%d).log"
ALERT_FILE="/tmp/utm_alert.txt"
WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=你的token"
failed_count=0
while IFS='|' read -r channel name url; do
[[ -z "$url" || "$url" =~ ^# ]] && continue
final_url=$(curl -L -s -o /dev/null -w '%{url_effective}' --max-time 10 "$url")
status_code=$(curl -L -s -o /dev/null -w '%{http_code}' --max-time 10 "$url")
if echo "$final_url" | grep -qiE "utm_source|utm_medium"; then
echo "[OK] [$channel] $name" >> "$LOG_FILE"
else
failed_count=$((failed_count + 1))
echo "[FAIL] [$channel] $name → $final_url (HTTP $status_code)" >> "$LOG_FILE"
echo "- **[$channel]** $name: 参数丢失,最终URL: $final_url" >> "$ALERT_FILE"
fi
done < "$URL_FILE"
# 有失败才发告警
if [ "$failed_count" -gt 0 ]; then
alert_text=$(cat "$ALERT_FILE" | tr '\n' '\\n')
curl -s -X POST "$WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{\"msgtype\": \"text\", \"text\": {\"content\": \"⚠️ UTM参数丢失告警\\n共检测失败 $failed_count 条链接:\\n$alert_text\"}}"
rm -f "$ALERT_FILE"
fi
echo "巡检完成:检测失败 $failed_count 条"
crontab配置
# 每天上午9点自动检测营销链接UTM参数
0 9 * * * /bin/bash /data/scripts/utm_check.sh >> /data/marketing/cron.log 2>&1
五、参数检测的关键细节
1. -L参数必须加
不加-L,curl不会跟随重定向,你拿到的只是第一跳的响应,根本不是用户最终看到的URL。检测参数保留必须让curl走完全部重定向链路。
2. url_effective才是最终地址
-w '%{url_effective}'输出的才是用户浏览器最终显示的URL。不要用url_redirect(那是第一次跳转的目标地址)。
3. 注意哪些参数在检查
不同业务的UTM参数组合不一样。电商可能用utm_source + utm_medium + utm_campaign,内容平台可能还加了utm_content + utm_term。根据自己业务调整grep的匹配模式。
4. 超时设置要合理
营销短链跳转可能涉及多级302,响应时间较长。建议--max-time 10起步,如果是批量检测几百条链接,配合xargs -P并行处理更高效。
六、三个方案怎么选?
- 方案一(基础版):适合临时检查几十条链接,快速出结果。打开Excel看CSV,一眼就知道哪些链接参数丢了。
- 方案二(进阶版):适合多渠道投放团队,需要按渠道维度看数据。报告自动统计保留率,定位问题渠道效率高。
- 方案三(自动巡检版):适合生产环境长期运营,挂crontab每天自动跑。有问题钉钉/邮件自动告警,真正做到无人值守。
实际使用中,建议先用方案二做一轮全面排查,定位有问题的渠道和链接,修复后再用方案三做日常巡检。参数保留率从60%提升到99%以上,是完全可以做到的。
七、相关文章推荐
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论