news 2026/9/8 9:41:55

Python微信公众号爬虫实战:从抓包到数据落库的完整方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python微信公众号爬虫实战:从抓包到数据落库的完整方案

简介:面向微信公众号文章采集需求的爬虫实践资源,适合有基础编程知识、希望批量获取公众号所有文章链接的开发者与数据分析人员。资源围绕微信公众号平台文章链接获取展开,讲解从登录凭证取得、请求接口、解析参数到输出结果的一整套流程,可用于内容归档、传播分析、学术研究等方向。压缩包共三十个文件,以十三个Python脚本为核心,分别处理文章地址提取、文章信息读取、接口调用封装等任务;另附五份Markdown文档,说明微信参数获取与常用接口的使用细节,并用多张图片截图辅助理解,还带有浏览器驱动及配置文件,整体十七点二二MB,目录结构清晰。目前已有五百八十人学习浏览,借助配套文档可快速完成环境搭建与脚本调试;模块化设计也方便按需修改,扩展为定制化采集工具。 说句实话,但凡接触过公众号数据分析的人,迟早都会走到爬虫这一步。公众号文章不像普通网页那样有清晰的静态HTML,也不提供公开的聚合接口,想拿到历史文章列表、正文、评论数据,就得在官方限制和个人研究需求之间找一条能走通的路。这个项目标题是“Python-微信公众号的爬虫”,核心关键词就三个:Python、微信公众号、爬虫。Python只是工具,真正的难点在于弄懂公众号数据从哪来、怎么拿、拿到后怎么解析——这才是整个项目最花时间的地方。

这篇文章我打算按自己实际做过的方案来写:先讲清楚公众号数据获取的几条路线,再对比为什么选PC端抓包这条路;然后从环境准备、核心字段解析、请求流程、正文提取、缓存解析到常见问题排查,一步步展开。适合的人很明确:想用Python拉取公众号文章做数据分析、知识库构建、内容监控的开发者;刚入门爬虫、但对微信公众号这种“半封闭”场景感兴趣的人,也能从中找到一条可以落地的完整链路。

1. 先搞懂数据从哪里来:四条可行的路线

网上聊公众号爬虫,方案五花八门,但真正能用的核心路线其实是固定的四条。我一开始也踩过不少弯路,总觉得“官方有接口但权限不够,那就找别的入口”,结果每条路都有自己的坑。这里先把四条路线讲清楚,后面再展开最稳的实操方案。

1.1 官方接口路线:权限门槛比想象中高

微信公众平台官方提供了内容管理接口,但注意,这个接口不是给爬虫用的。它面向的是公众号运营者本人,要求你拥有公众号后台权限,而且仅仅能拉取自己账号的历史文章列表和各项统计数据。想通过微信开放平台接口去抓别人的公众号文章,基本是行不通的,权限模型里就没有这个授权方向。所以如果你研究的是“爬取任意公众号文章”,官方接口这条路可以先放一边。

1.2 搜狗微信搜索路线:入口公开但限制太多

搜狗有一个“搜狗微信搜索”,按公众号名称或者文章标题可以搜到部分公众号内容。这个入口的好处是不需要登录、不需要任何微信身份,直接requests请求就行。坏处也很明显:反爬机制非常严格,经常让人“验证码”拦下来,而且搜到的文章不全、有时效性,只覆盖最近一段时间的部分内容,不是完整历史库。适合小批量、低频率地搜某篇文章是否被收录,不适合做系统性采集。

1.3 PC端代理抓包路线:多数个人项目的首选

这是我个人强烈推荐的一条路。微信PC客户端在Windows上会持续接收公众号消息,当你点开一个公众号的历史消息列表时,客户端会向微信服务器发起一个真正的JSON接口请求。如果我们在PC上配置一个本地代理(比如mitmproxy),就能截获这个请求,拿到接口地址、请求参数和返回数据。基于这些数据,你可以用Python模拟客户端继续请求历史列表,从而实现“翻页读取”,覆盖一个公众号的大部分历史文章。

1.4 本地缓存解析路线:适合做存量数据恢复

微信PC客户端会缓存已加载过的公众号文章,文章内容、封面图、摘要都可能落在本地数据库文件中。如果你只是想恢复自己账号“曾经浏览过”的文章内容,解析本地缓存是最直接的办法,不需要联网请求接口。但它的局限在于:你只能拿到这个客户端“看过”的公众号内容,无法自由扩展到一个全新公众号的全部历史文章。

四条路放一起对比:

路线数据完整性破解难度防封风险适用范围
官方接口仅限本账号自己公众号的数据统计
搜狗微信搜索部分且滞后单篇临时搜索、验证收录
PC端代理抓包高,可翻页抓取任意公众号历史文章
本地缓存解析仅限已浏览恢复浏览过的存量内容

整体看下来,PC端代理抓包是性价比最高的方案,后面两章按这个路线展开。

2. 环境准备与核心工具选型

实战之前先确认环境。这个项目的技术栈很清晰:Python 3.8以上 + requests + mitmproxy + 数据库存储工具。下面把每一个工具的必要性和选型理由说清楚,避免你装了一堆用不上的库。

2.1 Python环境与依赖库

如果你机器上还没有Python,建议直接装Anaconda或者从Python官网下载安装包,勾选“Add Python to PATH”。装完之后用pip安装几个关键库:

pip install requests pip install mitmproxy pip install pyquery pip install sqlite3 # 标准库自带的sqlite3模块,一般不用额外安装

requests是发HTTP请求用的,三个核心能力用得上:Session会话保持(自动携带cookie)、自定义Header、超时重试。pyquery用于解析文章正文里的HTML,比正则表达式好维护得多。sqlite3用于本地存储抓取结果,结构化数据直接落表。

2.2 Windows上定位微信客户端缓存目录

这个在热词里几乎每个月都有人问:微信PC客户端的公众号推送缓存在哪里?答案是它不是固定不变的,不同版本差异较大。最常见的路径是:

C:\Users\你的用户名\Documents\WeChat Files\你的微信号\SNS\

如果你的微信版本比较新,可能在“FileStorage”目录下,或者是“Applet”相关的子目录。更省力的方式是用Everything搜索工具,直接搜“SNS”或“FileStorage”关键字,按最近修改时间排序,最后修改的数据库文件就是当前正在写入的缓存库。注意,这个路径下可能有多个账号的目录,需要先通过文件修改时间确定当前登录的微信号。

2.3 mitmproxy的安装与启动

mitmproxy是一个开源的中间人代理工具,它可以在本机启动一个代理端口,捕获本机进程发出的HTTP/HTTPS请求。正因为微信PC客户端走的是HTTPS,所以我们首先要让mitmproxy拿到SSL加解密的能力:运行一次mitmweb,把mitmproxy的根证书安装到Windows系统“受信任的根证书颁发机构”中,这样微信客户端请求HTTPS接口时,数据包就能被本地代理正常解密。

启动命令很简单:

mitmweb -p 8080 -w flows.mitm

其中-p 8080指定监听端口,-w flows.mitm把捕获到的流量实时写入文件,方便后续离线分析。

选mitmproxy而不是Fiddler或Charles,关键原因是它原生支持Python脚本扩展,你可以写一个addon脚本把特定接口的请求和响应自动保存成JSON。这一步直接把“抓包”和“写爬虫”衔接起来了。

3. 实操:从PC端抓取公众号文章列表的完整链路

环境就绪后,接下来就是整个项目最核心的部分:拿到公众号历史文章列表的请求,理解它的参数,再让Python把这个流程自动化。

3.1 用mitmproxy捕获历史列表请求

操作步骤很简单:先在Windows系统设置里开启“手动代理”,地址填127.0.0.1,端口填8080。然后打开微信PC客户端,进入任意一个公众号的“历史消息”页面,下拉刷新几次。

此时切回mitmweb界面,在请求列表中过滤一下,重点关注请求URL中包含cgi-bin/appmsgpublishcgi-bin/appmsg关键字的数据包。这两个接口是公众号历史文章列表的核心入口,一个用于获取“发布列表”,一个用于获取“文章列表数据”。找到之后,把请求头、请求参数、响应JSON整体复制下来。

3.2 拆解核心参数:__biz与appmsg_token

拿到的请求URL和参数里,最关键的字段有三个:

  • __biz:公众号的唯一业务标识,每个公众号对应一个固定值,相当于公众号在微信服务器中的身份证号。
  • appmsg_token:访问令牌,由微信客户端在会话中动态生成,它的有效期很短,实测大约5分钟左右就会过期,不能复用,必须每次从新鲜请求中获取。
  • cookie:请求的凭证信息,其中包含wap_sid2等关键字段。也是短时效的,过期后需要重新登录微信客户端再抓一次。

这里就能看出为什么“直接用requests调用接口”的方案很难长久:token刷新机制太频繁了,你很难凭一个“固定的cookie”长期跑。我自己常用的做法是,先用mitmproxy抓一次完整请求,把参数固化到本地配置,然后写一个定时任务每3-4分钟重新捕获一次新token,保持请求生命周期不过期。如果只是短时间跑一次脚本,手工复制参数完全够用。

3.3 编写文章列表请求脚本

拿到token参数之后,就可以写第一个真正能跑的脚本了。核心逻辑是:用requests.Session把请求头补全,提交POST请求,解析返回的JSON。代码如下:

import requests import json import time # 从mitmproxy抓包结果中复制出来的固定参数 BIZ = "你的__biz值" TOKEN = "你的appmsg_token值" COOKIE = "抓包得到的完整Cookie" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Referer": f"https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz={BIZ}", "Cookie": COOKIE, } params = { "__biz": BIZ, "appmsg_token": TOKEN, "action": "list_ex", "begin": "0", # 分页起始位置,第一次从0开始 "count": "10", # 每页条数,实测10条最稳定 "f": "json", } url = "https://mp.weixin.qq.com/mp/profile_ext" def fetch_article_list(): resp = requests.post(url, headers=headers, params=params, timeout=10) data = resp.json() if data.get("ret") == 0: return data.get("general_msg_list"), data.get("can_msg_continue"), data.get("next_offset") else: print("请求失败,返回错误码:", data.get("ret"), data.get("errmsg")) return None, False, None if __name__ == "__main__": msg_list, can_continue, next_offset = fetch_article_list() if msg_list: msg_list = json.loads(msg_list) for msg in msg_list.get("list", []): app_msg_list = msg.get("app_msg_list", []) for article in app_msg_list: print(article.get("title"), article.get("link"))

这段代码的关键点在第32行附近:请求返回的general_msg_list默认是字符串格式,必须先json.loads再遍历,不然很容易栽在“明明有数据却打印不出内容”的坑上。can_msg_continue为1时表示还有下一页,next_offset作为下一次请求的begin参数。

3.4 翻页逻辑和正文提取

翻页逻辑很简单,用一个while循环就行。唯一要注意的是每次翻页的间隔建议设置在3到5秒以上,别问为什么,问就是太快会被微信风控,返回的ret码会变成非0值。

拿到文章链接后,正文提取有两种方式:

第一种是直接用requests请求文章链接,链接里已经包含__biz和idx参数,返回的是完整HTML,用pyquery定位div#js_content节点就能拿到正文。这种方式适合大部分文章,代码量不大:

from pyquery import PyQuery as pq html = requests.get(article_url, headers=headers).text doc = pq(html) content = doc("#js_content").text()

第二种是直接解析文章链接中的sn参数,拼请求去调用“获取文章内容”的接口。这种方式更稳定,因为HTML页面里的图片加载方式可能被微信处理成懒加载,直接请求接口返回的JSON会干净很多。如果遇到正文提取不全的情况,优先换成接口方式。

3.5 数据落库与增量更新

抓取的字段至少包括:文章标题、链接、摘要、封面图、发布时间、正文内容。存到sqlite里建一张表,以文章链接作为唯一索引,实现增量更新:

CREATE TABLE IF NOT EXISTS articles ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, url TEXT UNIQUE, summary TEXT, cover_img TEXT, publish_time INTEGER, content TEXT );

插入时用INSERT OR IGNORE,遇到重复链接直接跳过,这样每次脚本只处理新增的文章,比较高效。我习惯每次抓完写一个简单的统计日志,打印本次新增条数和总条数,方便快速核对数据有没有断层。

4. 补充路线:本地缓存解析的思路

前面说过,本地缓存解析适合恢复本机已浏览过的文章内容。这里补充两个实际会遇到的坑,给需要走这条路的朋友一点参考。

4.1 怎么判断缓存文件是否加密

微信PC客户端的缓存数据库文件,在不同版本里区别巨大。老版本里很多是明文SQLite,直接用DB Browser打开就能看到表结构;新版本部分数据库采用了加密格式,文件名后缀仍然是db,但内容已经不是标准文件头了。判断方法很简单:用16进制编辑器打开文件,如果文件头部是“SQLite format 3”这串ASCII,就是明文库;如果不是,基本可以确认加密了。

4.2 缓存解析需要注意的边界

加密数据库的密钥一般跟当前登录账号相关,不同版本提取方式不同,网上也有一些开源工具做过这件事。但从数据体量和使用场景看,我更推荐把本地缓存作为“辅助恢复手段”,主力仍然放在抓包接口上。因为缓存库里只有你“看过”的公众号文章,文章列表不全,数据量完全看你的浏览历史,参考价值毕竟有限。假如你只是想把个人历史浏览记录导出成自己读,这条路很省事;如果你要构建一个公众号内容监控系统,还是要走第3章的接口方案。

5. 常见问题与排查技巧实录

不管方案多完整,实际跑起来总会遇到各种问题。下面整理我在这个项目里遇到频率最高的几类问题,按从“出现频率高到低”的顺序写。

5.1 token过期和cookie失效

这是最最常见的报错,表现是请求返回ret: 200003或者invalid appmsg_token。pandas解法很固定:重新到微信PC客户端里刷新一次公众号历史消息页面,同步到mitmproxy里抓最新参数。我个人的经验是,把token和cookie直接存到一个独立的配置文件里,每次跑脚本前手动更新一次,配合定时任务提醒,比写复杂自动刷token代码更省心。

5.2 返回ret非0的其它情况

如果返回码不是0,先对照下面这张表:

返回码常见原因处理办法
0正常
200003访问令牌无效或过期重新抓包新token
200013频率过高被限制等待10-30分钟,降低请求频率
1参数错误检查__biz、begin、count格式
-3签名错误检查cookie是否完整、请求头是否有遗漏

5.3 某些文章正文为空

遇到这种情况,先用浏览器打开文章链接手动验证能否正常访问。如果浏览器能打开但脚本拿不到正文,大概率是页面里的懒加载机制导致的。处理方式是把pyquery的解析目标从#js_content改成rich_media_content类名,或者改用文章内容JSON接口。

5.4 抓取过程中被风控

这一条必须认真讲。微信的风控不是看你单次请求多快,而是看“行为是否符合人体操作规律”。连续翻页几十次不带停顿、单次请求间隔固定为3秒整、每天抓取同一公众号上千次,这些机器行为很容易触发限制。应对策略是:随机化请求间隔(比如3到8秒随机)、设置每天总抓取量上限、对多个公众号轮换访问而不是盯着一个号使劲刷。

6. 数据边界与合法使用红线

做到最后一步,一定要聊一下数据使用的边界。爬虫技术本身是中性的,公众号文章的内容版权依旧归属于原作者和平台。代码能把JSON请求发出去、把HTML解析干净,但代码不能替你做数据合规决策。

我自己的实践原则是三条:

第一,只能把抓取到的数据用于个人学习、内容聚合阅读、非商业性质的统计分析;如果要做产品,需要提前确认内容的使用授权。

第二,抓取频率必须克制,不要给目标服务器和微信后台造成压力。有人会觉得“反正接口在那里,我多请求几次没事”,但实际被限制之后不仅账号受影响,连带着正常微信使用都会麻烦。

第三,公众号文章正文、图片、评论虽然可以被程序读取,但再次整理发布时要尊重原创,保留署名和来源链接;擅自搬运、洗稿同样不可取。

这几条算是给自己也给读者画一条清楚的下限,保证技术能推进,也不至于触线。


最后说点项目实操的体会。做微信公众号爬虫,最容易出现的情绪是“开头信心满满,中途被token和风控磨得没脾气”。我的建议是搭一个尽量简单的工程骨架:固定参数、独立配置文件、数据库表结构、日志输出,这四件套先跑通,不要一上来就追求“全自动无人值守”。踩过几次坑之后,你会发现真正的价值不只是拿到文章数据,而是你亲手理解了微信公众号这套半封闭系统的请求规律和数据结构——这套经验放到任何以“获取数据+解析数据”为核心的项目里,都通用。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 9:41:10

系统仿真体系化转型:从工具烟囱到长期演进的工程体系

“系统仿真”这个关键词,放在三五年前,多数人想到的还是某个物理场仿真工具、某款建模仿真软件;但这几年再到研发型企业和科研机构里转一圈,高频词已经变成了“体系”“平台”“中台”。我自己在系统仿真领域摸爬滚打了十几年&…

作者头像 李华
网站建设 2026/9/8 9:41:04

从单次模型调用到Agent Loop:复杂智能体架构设计实战

在实际的 Agent 项目中,模型单次调用和完整智能体之间,往往隔着一条比想象中更深的沟。很多开发者在本地跑通一次大模型调用之后,以为下一步只需要把提示词写长一点、多问几轮,就能得到一个自动执行任务的智能体。真正进入工具调用…

作者头像 李华
网站建设 2026/9/8 9:40:59

免费AI工具+Blender+虚幻引擎,单人搭建完整3D游戏关卡实战

搭建一个完整的3D游戏关卡,过去通常需要建模、地编、技术美术和程序协作完成:先在Blender里建资产,再导入虚幻引擎,摆放、打光、调碰撞,最后还要反复运行游戏验证可玩性。现在借助免费AI工具,单人也能把这套…

作者头像 李华
网站建设 2026/9/8 9:39:20

小米开源TabLDM:表格数据大模型登顶CTR基准

最近小米开源了一个专门针对表格结构化数据的大模型,叫 Xiaomi-TabLDM,并且重新回到了 OpenML-CTR23 这个榜单的第一名。看到这个消息的时候,我第一反应是比较兴奋的,倒不是因为它登顶,而是因为表格数据这个方向终于开…

作者头像 李华
网站建设 2026/9/8 9:38:02

机械革命极光X值不值得买?深度体验与验机避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/8 9:36:53

SSI获NVIDIA投资:10倍算力提升背后的异构计算调度优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华