最近在微信群看到 ROYWANG 写的一篇 《谁在悄悄关注你?给博客装上 RSS 订阅计数器》 ,博主做了个小脚本,来统计博客 RSS 订阅数,但那个脚本只适合博客域名托管至 Cloudflare 的情况。由于我的博客分别在 VPS 和 Vercel 上,情况又有所不同,趁着周末,我也稍微研究了一下这个问题,其实过程也非常简单。
统计原理
此前我写了一篇 在1panel中使用Goaccess取代网站监控和网页统计 的文章,对 Nginx 日志结构进行过一些研究,比如,下边这四条日志,分别代表有网友在 WordPress(应该是RSS插件), FressRSS, Tiny Tiny RSS, NetNewsWire RSS 客户端拉取我的博客更新。
1
2
3
4
| 88.88.88.88 - - [17/Jan/2026:06:02:39 +0000] "GET /index.xml HTTP/1.1" 200 92659 "-" "WordPress/6.9; https://www.domain.com" "-"
99.99.99.99 - - [17/Jan/2026:06:11:03 +0000] "GET /index.xml HTTP/2.0" 304 0 "-" "FreshRSS/1.28.0 (Linux; https://freshrss.org)" "-"
66.66.66.66 - - [17/Jan/2026:06:19:39 +0000] "GET /index.xml HTTP/1.1" 304 0 "-" "Tiny Tiny RSS/25.07-dea3f2d (Unsupported) (https://tt-rss.org/)" "-"
77.77.77.77 - - [17/Jan/2026:06:12:08 +0000] "GET /index.xml HTTP/2.0" 304 0 "-" "NetNewsWire (RSS Reader; https://netnewswire.com/)" "-"
|
由此,我们只需要将这些访问 index.xml 的 IP 和主机头进行统计即可,考虑到一般 RSS 拉取频率基本都在每天 2 次以上,因此我们只需要统计最近一天的独立访问数。为了避免误差,也可以统计一周甚至一个月的访问数,然后再跟一天的数据进行对比。
我博客的 VPS 日志路径一般在 /www/sites/lawtee.com/log/access.log。RSS 文件为 /index.xml。可以先用 grep 把相关请求提取出来:
1
| grep 'GET /index.xml' /www/sites/lawtee.com/log/access.log > rss.log
|
为了排除浏览器和爬虫访问,可以过滤掉常见 User-Agent:
1
| grep -Ev 'Mozilla|Chrome|Firefox|Safari|Edg|bot|Bot|spider|Spider|crawl|Crawl|Finder' rss.log > rss_clean.log
|
这样就能得到 VPS 上真实的 RSS 客户端访问记录。
解析访问日志
如前边示例,RSS 订阅客户端的访问日志一般包含 IP、时间和 User-Agent。我们可以用 awk 提取数据后再去重得到订阅数。
- 生成 rss_key.log
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| awk -F\" '{
# 第1段:IP + 时间
split($1, a, " ");
ip = a[1];
# 第4段形如:[17/Jan/2026:05:59:32
date_raw = a[4];
gsub("\\[", "", date_raw);
split(date_raw, d, ":");
date = d[1];
ua = $6;
print date "|" ip "|" ua;
}' rss_clean.log > rss_key.log
|
- 统计 IP+UA 的出现天数 + 次数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| awk -F\| '{
key = $2 "|" $3;
seen[key, $1] = 1;
count[key]++;
}
END {
for (k in count) {
day_count = 0;
for (x in seen) {
split(x, p, SUBSEP);
if (p[1] == k) day_count++;
}
if (day_count >= 3 && count[k] >= 10) {
print count[k], day_count, k;
}
}
}' rss_key.log | sort -nr > subscribers_strict.txt
|
- 统计订阅数
1
| wc -l subscribers_strict.txt
|
例如我 VPS 统计订阅数为 339 个。
Vercel 访问估算
Vercel 免费计划无法获取详细日志,但可以在 Observability/Edge Requests 中查看具体链接最近 12 小时以内的访问数次。比如,我这里查看过去 12 小时 /index.xml 访问次数为 349 次。假设用户访问行为与 VPS 相同,则 Vercel 订阅数可以按照 VPS 结果来进行估算 。
统计 VPS 上最近 12 小时访问次数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| awk '
$0 ~ /GET \/index.xml/ {
n = split($4, a, ":")
datehour = a[1]
sub("\\[", "", datehour)
mon = substr(datehour,4,3)
if (mon=="Jan") mon="01"
else if (mon=="Feb") mon="02"
else if (mon=="Mar") mon="03"
else if (mon=="Apr") mon="04"
else if (mon=="May") mon="05"
else if (mon=="Jun") mon="06"
else if (mon=="Jul") mon="07"
else if (mon=="Aug") mon="08"
else if (mon=="Sep") mon="09"
else if (mon=="Oct") mon="10"
else if (mon=="Nov") mon="11"
else if (mon=="Dec") mon="12"
day = substr(datehour,1,2)
year = substr(datehour,8,4)
hour = a[2]
ts = year mon day hour
if (ts >= "2026011618") {
print
}
}
' access.log > rss_12h.log
|
然后统计访问次数:
我这里统计出来的 12 小时访问次数为 393 次,按照前边 339 个订阅数计算,每个订阅数大概每 12 小时访问 1.17 次。以此估算,Vercel 那边 349 次访问数,大概对应 300 个订阅数。
将 VPS 和 Vercel 合并,可以得到我这里全站订阅人数保守估算为 339 + 300 ≈ 639。但无论是前边提到 ROYWANG 那种方法,还是我这里的方法,都无法得出实际订阅人数。
原因在于一些现代 RSS 平台,比如 Folo.is(之前叫 Follow.is),它并不是按传统 RSS 逻辑拉取内容,而是完全模拟浏览器行为访问网站。这种访问模式会触发普通网页和资源请求,而不是单独拉取 /index.xml 或 /feed/,所以日志里看到的访问次数和传统订阅行为完全不同,无法通过简单去重或访问频率来推算真实订阅人数。
因此,日志统计方法更多适用于 传统 RSS 客户端,对于像 Folo.is 这种平台,只能得出访问量或流量估算,而无法直接反映实际订阅用户数量。