公众号历史文章数据采集与Excel分析实战:以罗辑思维为例 1. 项目全景从“看文章”到“看数据”1.1 这个项目到底在做什么罗辑思维这个号是我公众号观察系列里第一批纳入样本的。前后筹备了一周把2025年发布的874篇文章全部抓下来整理成Excel包含标题、发布时间、链接、阅读数、点赞数、推荐数、分享数、留言数。做完之后发现一个很有意思的数字10万的文章有147篇整体爆文率接近16.8%。这个项目本质上做的是一件事把公众号从“内容产品”变成“数据样本”。很多做运营的朋友每天在看文章、转文章但对“这个号到底发了什么、哪些内容真正跑出来了、用户在看什么之后愿意互动”这些问题基本上是凭感觉。我这几年的经验是感觉会骗人数据不会。把一年的发文记录拉出来排个序、分个层、算个比例很多运营上的门道一下就清楚了。这篇长文想把整个流程完整交代一遍数据怎么抓、字段怎么定义、Excel怎么生成、统计结果怎么看以及我在这个过程中踩过的坑。适合三类人做新媒体运营的、搞数据分析的、纯粹想研究头部公众号内容节奏的。我默认你懂一点Python不太懂也没关系代码可以直接抄每一步为什么这么做我会讲清楚。1.2 为什么选“罗辑思维”这个观察样本选样本这事很多人不重视觉得随便找一个号就能跑通流程。实际上样本选得好不好直接决定后续分析有没有意思。我当时挑罗辑思维主要看中几点。第一更新频率够高。这个号基本保持日更有些天甚至会发三到四篇一年下来能凑出874篇有效记录。样本量大了之后做时间分布、标题规律这类分析才有统计意义。如果找一个周更的号一年才五十篇做出来的观察报告很薄也看不出什么趋势。第二文章形态足够杂。有长文、有短观点、有书摘、有商业案例分析、也有知识付费产品的推广文案。形态杂意味着阅读数、点赞数、留言数这些指标分化明显分析时能看出不同内容类型之间的差异。我手动翻的时候感觉篇篇都挺有道理但数据拉出来之后才发现有些类型的文章阅读量离10万差得很远。第三10万文章的比例足够高又没高到失去区分度。147篇10万意味着这个号确实有稳定的大众触达能力但剩下727篇没有到10万这给对比分析留出了空间。如果全都能到10万反而没法分析“什么内容更容易爆”。说白了选样本的标准就三条有量、有差异、有分层。满足这三条哪怕你选的是一个垂直领域的万粉小号同样能做出一份有价值的观察报告。1.3 为什么坚持导出Excel而不是只写分析代码有人可能觉得数据分析直接用Python打印结果就行为什么非要导成Excel我做这个项目时从第一天就定了规矩最终交付物一定是一份Excel文件而且要做得让不懂代码的人也能直接用。一个很现实的原因是运营团队里不是每个人都愿意跑命令行。把数据导成Excel之后同事可以自己筛选“阅读数大于5万的标题有哪些”可以拖一个数据透视表看“哪个月发得最多”甚至可以直接把某一列复制进汇报PPT。我见过太多分析项目Python脚本写得漂漂亮亮但分析结果只在工程师的终端里业务人员根本够不着最后项目就烂尾了。另一个原因是Excel本身在几千行的数据规模下非常好用。很多人搜过“Excel函数公式大全”也收藏过不少技巧但真到处理八百多行数据的时候反而觉得 Excel 不够用。这个认知是错的。874篇文章构成的二维表用数据透视表、条件格式、自动筛选处理起来非常顺手完全没必要上数据库。先导出Excel让数据“落地”后续要导进BI工具、接入RPA或者转成CSV喂给其他程序都有回旋余地。2. 数据采集方案怎样拿到公众号历史文章2.1 三条获取文章列表的路径要拿到一个公众号的历史文章市面上的做法大致分三类我的建议是优先级从上往下排。第一类公众号自己的合集/专辑页。微信公众号后台推出“合集”功能之后运营者会把同主题的文章归到一个专辑里。专辑页有一个公开的URL顺着它能拿到一连串的文章标题、封面、摘要和发布时间。这个路径最干净数据是结构化的而且不需要登录就能看到前几十篇。罗辑思维这个号内容体系性强合集页给整个采集流程省了很多事。第二类第三方新媒体数据平台。新榜、清博这类平台都已经把公众号历史文章目录化提供了按账号查看文章列表的功能。它们的字段比原始页面更规整有些还直接给出了阅读数、点赞数等指标的估算值。但问题也很明显非会员能看到的数据量有限字段精细度不够而且不同平台的口径可能不一致。用这类平台做交叉验证没问题做主力数据源不太够。第三类搜狗微信搜索。这是老牌入口直接搜公众号名就能看到最近十篇文章还附带阅读数和点赞数。但搜狗的限制非常严格翻页困难、反爬明显、数据深度有限只适合临时查一篇文章不适合批量拉全量数据。我试过用它跑整个流程跑了一半就放弃了。实际执行时我走的是“合集页拿文章列表 文章详情页拿互动指标”的组合路。先拿到“有哪些文章”再逐篇去取“每篇表现如何”两段数据用文章链接作为主键关联最后合成一张宽表。这个思路对任何公众号都通用不管对方有没有开合集你只需要找到它的文章入口就行。2.2 字段拆解阅读数、点赞数、推荐数、分享数、留言数到底指什么采集之前必须先把字段定义搞清楚。不然后面统计出来数字对不上自己都不知道错在哪。我这套Excel里最终落地的字段有八个文章标题、发布时间、链接、阅读数、点赞数、推荐数、分享数、留言数。文章标题和链接好理解直接从文章页HTML里能抓。发布时间也好办文章页有一串Unix时间戳转换一下就是标准日期时间。这里注意一个坑标题里可能带换行和多余空格直接进Excel会显得很乱后面清洗阶段要专门处理。阅读数对应文章页下方的“阅读”数字。这里有一个全行业都知道的特殊规则超过10万之后页面只显示“10万”不再显示精确数字。所以我在Excel里单独加了一列“是否10万”用逻辑值标记清楚方便后面筛爆文。文章详情接口如果返回精确数字当然直接填进去如果只返回“100001”这种占位符我就统一按照10万处理。点赞数页面上的“点赞”按钮对应的数值。这个指标在不同时期有过变化早期是“点赞”后来改成“在看”最近又改成“推荐”所以在旧文章和新文章之间做跨期对比时要留意按钮名称对应的字段到底是谁。我这套表格里把“点赞数”和“推荐数”分开列避免混在一起算不清楚。推荐数也就是现在文章底部的“推荐”按钮数据。微信改版之后用户可以把文章推荐给自己的朋友这个动作比单纯的点赞重一些接近早期的“在看”。接口返回的字段名在不同公众号上可能不一样我自己的处理原则是以自己抓包看到的返回值为准在Excel里用固定列名同时保留原始字段备注说明。分享数指用户把文章转发给好友或朋友圈的次数。这个值不直接在页面正文展示但接口能拿到。分享数是衡量内容“主动传播力”的关键指标比阅读数更能说明问题——一篇被分享很多但阅读一般的文章往往意味着它在小圈层内的精准传播。留言数就是文章留言区的评论总条数。留言需要作者精选后才会公开所以留言数高一方面说明讨论热烈另一方面也说明运营者在评论区互动上花过心思。留言数这个指标我自己在统计时单独用了接口数据没用页面肉眼数因为有些长文评论能有好几百条人工数根本数不过来。2.3 合规与频率控制数据采集的底线这一节是我每次讲公众号采集都必须强调的不是因为场面话而是我确实见过有人因为不管不顾地爬最后账号被封、数据白抓。先说合规底线。公众号文章页、合集页本质上是公开内容我把它们的标题、时间、链接和展示出来的互动数据记录下来用于个人观察和分析这属于对公开信息的整理。但如果把目光转向用户头像、昵称、评论者个人信息性质就变了。这个项目的原则非常明确只采集文章自身的数据绝不采集任何用户个人信息。留言数我取的是“有几条留言”不是“谁留了什么言”。再说频率控制。微信公众号对非登录状态下的接口请求是有风控的短时间高频请求很容易触发验证码甚至是IP限流。我自己的经验是同一IP下请求间隔不要低于1.5秒并且每次请求之间加一个随机延迟把“看起来像人手点击”的节奏模拟出来。整个874篇跑完我大概用了两个多小时中间还主动停了几次这个速度完全够用没必要贪快。第三个建议是做断点续采。文章列表分页拉到一半断网、程序崩了、电脑睡眠都是现实会遇到的场景。我一开始没做检查点断了就得从头来特别浪费时间。后来改进成每抓完一篇文章就往本地文件里追加一行就算中途崩了下次启动时先读一下已经抓到的链接集合跳过这些再做增量。这个做法后来帮我省了不少事。3. 数据处理与Excel导出从杂乱JSON到规整表格3.1 数据清洗的标准动作抓下来的原始数据不能直接写进Excel。接口返回的JSON和页面解析出来的文本多多少少都有脏东西不清理的话后面的透视表、排序、筛选全都会出错。清洗流程我一般固定做四步。第一步是去重。文章链接是唯一主键我从合集页拿到的列表和补采的详情数据里可能重复出现同一篇文章直接用链接去重保留信息最全的那一条。参数拼接顺序不同的URL需要先做归一化否则同一个链接因为参数顺序不对会被当成两条记录。第二步是格式化时间。接口返回的发布时间是一个十位或十三位的时间戳我用datetime模块转成“2025-03-15 08:30:00”这种标准格式同时拆出一列“日期”和一列“时刻”方便后面按日汇总和按小时分析。这一步很多人偷懒不做结果Excel里全是数字串图表都画不了。第三步是标题清洗。标题里的换行符、制表符、首尾空格全部清掉再把标题长度单列统计出来。后面分析的时候我要用标题长度和阅读数做简单对比看是不是短标题更容易爆。这个分析虽然粗糙但确实能看出一些倾向。第四步是数值字段的兜底处理。阅读数、点赞数这些字段有可能返回空值或字符串“None”我把它们统一转成0同时保留一列“是否缺失”作为诊断标记。宁可明明白白地知道这条数据没抓到也不要让空值混进平均值计算里把整体数据带偏。清洗完之后我会做一次全量巡检看看总共多少条、缺失值占比多少、时间范围是否覆盖全年、有没有明显的异常值比如某篇文章阅读数是隔壁文章的几百倍。巡检没问题才进入Excel导出阶段。3.2 用Python三件套实现Excel导出整个项目我只用了三个Python库requests抓取、pandas处理表格、openpyxl写Excel。这三个库加在一起已经能把这件事从头做到尾。先看抓取部分的核心逻辑。文章详情接口和公开页面返回的数据最终会汇总成一条条记录追加到一个列表里import requests import time import random from datetime import datetime HEADERS { User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.40(0x18002833) NetType/WIFI Language/zh_CN, Referer: https://mp.weixin.qq.com/ } def fetch_article_meta(url): # 文章详情页解析标题、发布时间、链接 r requests.get(url, headersHEADERS, timeout10) # 实际解析需要从HTML中提取 var msg_title、ct 等字段 # 这里省略正则细节把解析结果作为字典返回 return { 标题: 示例标题, 发布时间: 2025-06-18 08:00:00, 链接: url, } def fetch_read_stats(biz, mid, idx, sn, token): # 阅读数、点赞数、推荐数、分享数、留言数 api https://mp.weixin.qq.com/mp/getappmsgext params { __biz: biz, appmsg_type: 9, mid: mid, idx: idx, sn: sn, is_ok: 1, f: json, token: token, } r requests.get(api, paramsparams, headersHEADERS, timeout10) return r.json()这里有两个提醒。第一微信对UAUser-Agent访问者浏览器标识是有要求的直接拿普通浏览器的UA去访问文章页大概率被拒。我同事踩过一次坑明明链接在微信里能正常打开用requests一访问就返回403。后来把UA改成微信内置浏览器的格式问题就解决了。第二阅读数等互动数据并不在文章页正文里而是要调getappmsgext这个接口参数里的__biz、mid、idx、sn必须从文章链接或页面源码里解析出来token也有时效过期之后要重新想办法获取。抓完之后把records装进pandas的DataFrame再做一次最后的清洗然后写Excelimport pandas as pd from openpyxl import load_workbook from openpyxl.formatting.rule import CellIsRule from openpyxl.styles import PatternFill df pd.DataFrame(records) # 判断是否为10万文章 df[是否10万] df[阅读数] 100000 # 按月统计 df[发布时间] pd.to_datetime(df[发布时间]) df[月份] df[发布时间].dt.to_period(M) monthly df.groupby(月份).agg( 总发布数(标题, count), 爆文数(是否10万, sum) ).reset_index() with pd.ExcelWriter(罗辑思维_2025观察.xlsx, engineopenpyxl) as writer: df.to_excel(writer, sheet_name文章总表, indexFalse) monthly.to_excel(writer, sheet_name月度发布统计, indexFalse) df[df[是否10万]].to_excel(writer, sheet_name10万清单, indexFalse) # 给文章总表加条件格式 wb load_workbook(罗辑思维_2025观察.xlsx) ws wb[文章总表] green_fill PatternFill(start_colorC6EFCE, end_colorC6EFCE, fill_typesolid) ws.conditional_formatting.add( J2:J875, CellIsRule(operatorgreaterThanOrEqual, formula[100000], fillgreen_fill) ) wb.save(罗辑思维_2025观察.xlsx)这段代码跑完之后Excel里会有三个Sheet文章总表、月度发布统计、10万清单。总表里每一行是一篇文章月度统计里每个月一行10万清单则单独列出所有爆文。三个Sheet对应三种看数据的视角日常用的时候不会混。3.3 让Excel更耐用的三个细节导出Excel只是及格线真正好用的表格还需要再做三个细节处理。我第一次做出的表格给同事用对方反馈是“能用但不好用”问题就出在细节上。第一日期一定要设置成Excel能够识别的格式。直接写入字符串“2025-06-18 08:00:00”Excel不一定把它当成日期筛选时无法按年月分组。我的做法是在写入前用pandas把它转成datetime类型这样Excel会识别为真正的日期自动筛选和透视表都能按年月层级展开。第二链接要带跳转动作。文章链接光放在单元格里别人要看还得复制粘贴到浏览器很麻烦。我通常会在Excel里加一列“文章跳转”用公式HYPERLINK(A2,打开原文)这样读者单击就能跳转。这个细节特别有效我上次发给运营同事对方第一反应就是“这个太方便了”。如果你不喜欢公式也可以直接用openpyxl给单元格加超链接属性效果一样。第三加一列“是否10万”并用条件格式把爆文行标出来。10万的界限是100000条件格式选“大于或等于”填充绿色整行都亮起来。这样一打开Excel哪些文章跑出来了眼睛一扫就知道根本不用再排序。我自己看数据时绿油油的一片就是月度的爆发时段灰扑扑的一片就说明那段时间内容整体没有破圈。还有一个容易被忽略的细节Excel里长数字比如链接URL容易被Excel自动识别成科学计数法看起来很别扭。解决办法是在写入之前给这一列设置单元格格式为“文本”或者干脆在URL前面加一个单引号。我用的是openpyxl读取后设置列格式这一招属于“查了半天才发现的坑”现在直接写出来省得你再踩。4. 2025年数据盘点874篇与147篇背后的信息量4.1 总量与发布时间规律874篇全年文章平均到365天差不多每天2.4篇。这个量级说明罗辑思维的内容生产不是“偶发式”的而是有明确排期、有稳定产能的。具体到一天之内发出几条拉开Excel就能看到节奏大部分天数是两到三条偶尔有四条的爆发日也有极个别天只发了一条甚至没发。发布时间分布是一个很有趣的维度。我按“小时”统计了一遍文章发布时间发现这个号的发文时间高度集中在几个固定窗口早上七点到八点一条中午十二点左右一条晚上六点到八点一条。这种“早中晚三段式”排期我判断是为了覆盖通勤、午休、睡前三个阅读高峰。推送时间本身就是运营策略的一部分很多用户就是习惯了在某个固定时间点收到它的文章久而久之形成了打开习惯。这里有一点值得做公众号的朋友参考如果你也想稳定出爆文不必追求每篇文章都十万加更重要的是让读者在固定时间看到你。数据里有大量阅读数在几千到两三万之间的文章它们虽然没爆但保持着账号的日常活跃度。真正撑起这个号基本盘的恰恰是这些“不爆”的文章带来的稳定触达。4.2 10万文章占比与特征观察147篇10万文章在874篇总量里占比约16.8%。如果把全年分成四个季度来看会发现这147篇并不是均匀分布的。我在Excel里用透视表粗略看了一眼明显有几个月份集中出现了大量10万还有一些月份几乎颗粒无收。这种月度差异通常和内容主题、热点事件、产品推广计划强相关值得单独列出来做深挖。我再做了一个很简单的特征对比把10万文章和全部文章的平均点赞数、平均推荐数、平均留言数分别算了一遍发现爆文的互动指标几乎全面高于非爆文。这个结果不意外但有一个细节很有意思——有些文章阅读数刚好还在五六万但留言数已经超过了部分10万文章。这说明小爆文不一定输在讨论热度上破圈和深度互动是两个维度。运营上如果只盯阅读数很容易错过评论区里那些真正高粘性的反馈。标题长度我也顺手统计了一下。不是想做什么严谨的结论但数据确实显示出一种倾向10万文章的标题普遍比非爆文更短、更直给。倒不是说长标题一定不好而是头部账号的内容盘子足够大短标题在信息流里被完整看到的概率更高损失的信息更少。这个观察对标题党没什么帮助但对老老实实做内容的人是有参考价值的。4.3 从数据反推运营节奏874篇文章的数据如果只看总量就太浪费了。我做这份Excel的核心目的是想反推出这个号的运营思路。比如说把“文章发布时间”和“是否10万”放在一起看能隐约看出早间时段发出的文章爆文比例比晚间略高。这个现象我推测和早间用户阅读行为有关早上大家愿意花时间看一篇有深度的文章晚上则更偏向于轻松的内容。当然这只是相关不是因果要验证还得再做更细致的内容分类。再比如说“推荐数”和“留言数”同时偏高的文章往往对应一些有争议性或者有现实意义的话题。有些内容阅读量中等但评论数和推荐数远远超出平均值说明它在核心读者群中引发了强烈的情绪共鸣。运营者完全可以依据这类指标去调整后续选题方向不必只盯着流量天花板。这个Excel对我来说最大的价值是它把“罗辑思维到底在靠什么保持影响力”这个问题变得可以回答高频、稳定、固定时段触达内容在长短之间切换爆文和常规内容交替评论区保持活跃。这些结论从外部看可能只是模糊的印象但一旦落到Excel里就变成了可以追溯、可以量化、可以作为对标参照的运营策略。5. 常见问题与排查经验踩过的坑一次说清5.1 抓取时拿不到阅读数怎么办这个问题我几乎每次做采集都会遇到公众号的互动数据接口有一定概率返回空值。排查方向按顺序来第一步检查UA是否模拟了微信内置浏览器。普通浏览器UA访问文章详情接口微信后台经常拒绝返回的JSON里没有read_num字段或者直接报错。这个问题最容易踩也最好修。第二步确认token是否过期。token是调用getappmsgext接口必需的凭证有时效性有效期过了之后接口会返回错误码。我的做法是在主流程里加了token刷新逻辑一旦检测到特定错误码就暂停任务重新获取token再继续。第三步确认文章链接中的参数配对是否正确。__biz、mid、idx、sn这四个参数必须来自同一篇文章混搭会出现“文章不存在”之类的提示。我当时还遇到过一个情况合集页拿到的链接和详情页拿到的链接参数排序不一致导致匹配不上后来统一用原始链接作为唯一标识问题就解决了。第四步如果以上都没问题大概率是阅读数已经超过10万接口返回的值为空或为占位符。这个时候不用纠结直接在Excel里标记为“10万”程序上不要让它影响整体入库。5.2 Excel导出后乱码、列错位、链接失效Excel导出环节也有不少细节问题。第一个坑是CSV编码。如果直接用Excel打开CSV文件中文会乱码因为CSV默认是ANSI编码Python写出来的往往是UTF-8。解决办法有两个一是写CSV时指定encodingutf-8-sig二是干脆不用CSV直接用pandas的ExcelWriter输出真正的xlsx格式这样根本不存在编码问题。我的选择是后者少一个坑就少一份烦恼。第二个坑是数字被Excel自动转成科学计数法。文章链接这种长串字符在Excel里很容易变成7.89E17这种样子。解决办法就是把链接列设成文本格式。我上面代码里写Excel的时候其实是可以用excel_writer的格式化选项预先处理的如果你用openpyxl做二次处理记得把链接列单元格的number_format设为。第三个坑是超链接失效。用HYPERLINK()公式生成的链接如果目标地址里带了或者?这样的特殊字符Excel有时会解析出问题。我的经验是链接如果来自微信文章页原样写入问题不大但如果是从抓包工具里复制、带了转义符的要先做一次URL解码再写入。5.3 频率限制与账号风险别等封号才后悔最后一定要讲频率限制。公众号的风控不是只针对登录态对匿名接口请求也有一整套识别逻辑。我同事曾经图快把请求间隔压到0.2秒结果跑了不到一百条就被提示操作频繁之后整个IP段一段时间内都没法正常访问文章页。这种代价太大了。我的做法是同一个IP下单篇文章的接口请求间隔不低于1.5秒再在这个基础上加随机延迟把间隔控制在1.5到3.5秒之间。整个874篇跑下来虽然时间多花了一点但全程没有触发风控数据一次性采集完整。如果你要采多个公众号更要注意控制总请求量不要在同一天内跑完所有目标账号拆成几天分批跑更稳妥。还有一件事我强烈建议每次采集都做增量备份。每抓完一篇就在本地记录一行不要等全部结束再一次性入库。我当时第一次做的时候没有这个思路跑到第四百篇时电脑自动更新重启前面抓的数据全丢了。后来改成增量追加模式就算中断重启后也能从上次断掉的地方接着跑。5.4 一份可复用的“采集-清洗-分析”流程模板这套流程跑通之后我把整套脚本做成了一个模板之后再做其他公众号的观察项目只需要替换公众号信息、调整字段映射基本可以开箱即用。整个流程分六步定位文章入口、抓取列表页、抓取详情页互动数据、清洗与去重、导出Excel、生成统计报表。我自己的建议是不要一开始就追求自动化到全流程一键跑通。第一步先把十篇文章跑通确认字段都对得上第二步扩大到一百篇看看有没有偶发错误第三步再全量跑这时候大概率会遇到的问题都已经提前暴露了。就像搭积木一样每一步稳了再往上走比一上来就写一个上千行的脚本然后调试三天要高效得多。如果你也想做类似观察建议先从自己关注的账号开始字段可以少一点三步跑通再加。阅读数、发布时间、链接这三列是最基础的先把这几个字段跑通再逐步加上点赞数、推荐数、留言数。等你把第一个账号完整地做成一份Excel后面的账号就只是换参数的问题了。