Skip to main content

wechat-article-parser

微信公众号文章解析器。传入一个公众号文章链接,自动抓取页面并提取公众号信息、文章元数据及正文的 Markdown 内容。

支持的文章类型:

  • 标准富文本文章
  • 转载式文章
  • 纯文本文章
  • 视频分享类文章
  • 小红书风格图片轮播文章
  • 全屏布局短文本文章

解析时优先读取页面全局的 item_show_type:0 对应图文、5 对应视频分享、 8 对应图片轮播、10 对应文字消息,再通过 HTML 或脚本数据区分具体模板。 类型字段缺失、值未知或对应分支未提取到正文时,会按原有 HTML 特征匹配顺序兜底。

安装

pip install wechat-article-parser

本地开发安装:

git clone https://github.com/huanjuedadehen/wechat-article-parser.git
cd wechat-article-parser
pip install -e ".[dev]"

依赖项(会自动安装):

  • Python >= 3.10
  • httpx
  • beautifulsoup4
  • markdownify

使用方式

同步调用

from wechat_article_parser import parse

result = parse("https://mp.weixin.qq.com/s/xxxxx")
print(result.article_title)
print(result.article_markdown)

异步调用

from wechat_article_parser import parse_async

result = await parse_async("https://mp.weixin.qq.com/s/xxxxx")
print(result.article_title)
print(result.article_markdown)

可选参数

两个方法都支持以下可选参数:

  • timeout:请求超时时间,单位秒,默认 15
  • user_agent:自定义 User-Agent,不传则使用内置默认值
  • proxy:HTTP/HTTPS 代理地址,不传则直连
  • include_raw_html:是否在返回结果中带上原始 HTML 网页源代码,默认 False
result = parse(
    "https://mp.weixin.qq.com/s/xxxxx",
    timeout=30,
    user_agent="MyBot/1.0",
    proxy="http://user:pass@127.0.0.1:7890",
    include_raw_html=True,
)

返回结构

parse 和 parse_async 均返回 ArticleResult 数据类,包含以下字段:

字段 类型 说明
mp_id_b64 str 公众号 ID(Base64 编码原始值)
mp_id int 公众号 ID(解码后的整数)
mp_name str 公众号名称
mp_alias str 公众号别名
mp_image str 公众号头像链接
mp_description str 公众号简介
mp_account_type AccountType 账号类型:AccountType.SUBSCRIPTION(订阅号)/ AccountType.SERVICE(服务号)/ AccountType.UNKNOWN(未识别)
article_id str 文章 ID
article_msg_id int 文章所在的群发消息 ID
article_idx int 群发图文中的位置(从 1 开始)
article_sn str 文章签名(防伪校验)
article_title str 文章标题
article_cover_image str 文章封面图链接
article_description str 文章摘要
article_markdown str 文章正文的 Markdown 内容;视频分享没有文字附言时可为空
article_publish_time int 发布时间(Unix 时间戳)
article_display_type ArticleDisplayType 文章展示类型:article、video、image、text 或 unknown
raw_html str 原始 HTML 网页源代码(仅在 include_raw_html=True 时填充,否则为空字符串)
images list[str] 文章中提取的所有图片链接
is_valid bool 关键字段是否全部解析成功(属性)

is_valid 为 True 的条件:mp_id、mp_name、article_id、article_msg_id、article_idx、article_sn、article_title、article_publish_time 均不为空/零,且 article_markdown 非空或 article_display_type == "video"。视频分享允许没有文字正文,仍须满足其他关键字段要求;有效性不表示已获取视频文件。

判断文章展示类型

ArticleDisplayType 是字符串枚举,既支持枚举比较,也支持语义字符串比较:

枚举 字符串值 含义
ArticleDisplayType.ARTICLE article 图文,包括转载式
ArticleDisplayType.VIDEO video 视频分享
ArticleDisplayType.IMAGE image 图片轮播
ArticleDisplayType.TEXT text 文字消息
ArticleDisplayType.UNKNOWN unknown 页面类型缺失或未支持
from wechat_article_parser import parse, ArticleDisplayType

result = parse("https://mp.weixin.qq.com/s/xxxxx")
if result.article_display_type == ArticleDisplayType.VIDEO:
    print("这是视频分享")

if result.article_display_type == "video":
    print("视频分享可以没有文字正文")

print(result.article_display_type)  # 例如 video

article_display_type 是返回结果中的数据字段,包含在 dataclasses.asdict(result) 中,JSON 序列化时输出语义字符串。 微信原始的 item_show_type 仅在解析器内部使用,不包含在返回结果中。

判断账号类型

AccountType 继承自 str 枚举,既支持枚举比较,也支持与中文字符串直接比较:

from wechat_article_parser import parse, AccountType

result = parse("https://mp.weixin.qq.com/s/xxxxx")

# 推荐:枚举比较(有类型提示与 IDE 补全)
if result.mp_account_type == AccountType.SERVICE:
    print("这是服务号")

# 也支持:字符串字面量比较
if result.mp_account_type == "服务号":
    print("这是服务号")

# 打印直接输出中文值
print(f"账号类型: {result.mp_account_type}")  # 账号类型: 订阅号

异常处理

WeChatVerifyError

当请求频率过高或 IP 被限流时,微信会返回验证码页面而非文章内容。此时会抛出 WeChatVerifyError:

from wechat_article_parser import parse, WeChatVerifyError

try:
    result = parse("https://mp.weixin.qq.com/s/xxxxx")
except WeChatVerifyError:
    print("触发了微信人机验证,请稍后重试或更换 IP")

httpx.HTTPStatusError

当 HTTP 请求返回非 2xx 状态码时,会抛出 httpx.HTTPStatusError:

import httpx
from wechat_article_parser import parse

try:
    result = parse("https://mp.weixin.qq.com/s/xxxxx")
except httpx.HTTPStatusError as e:
    print(f"请求失败: {e.response.status_code}")

解析不完整

缺少标题、发布时间等关键字段,或非视频分享缺少正文时,解析结果的 is_valid 会返回 False。封面图、摘要等非必填字段为空不影响有效性。建议在业务逻辑中检查:

result = parse("https://mp.weixin.qq.com/s/xxxxx")
if not result.is_valid:
    print("部分关键字段未能解析")

测试

安装开发依赖:

pip install -e ".[dev]"

运行全部测试

pytest tests/test_parser.py -v -s

只运行同步 / 异步测试

pytest tests/test_parser.py -v -s -k "sync"
pytest tests/test_parser.py -v -s -k "async"

测试单个链接 - 查看所有字段

pytest tests/test_parser.py::test_fetch_all -s --url "https://mp.weixin.qq.com/s/xxxxx"

测试单个链接 - 只看 Markdown 内容

pytest tests/test_parser.py::test_fetch_markdown -s --url "https://mp.weixin.qq.com/s/xxxxx"

测试单个链接 - 打印原始 HTML 网页源代码

pytest tests/test_parser.py::test_fetch_raw_html -s --url "https://mp.weixin.qq.com/s/xxxxx"

通过 HTTP 代理运行测试

所有测试命令都支持 --proxy 参数,传入后所有请求都会经由该代理;不传则直连。常用于 IP 被微信限流时换出口:

# 全量测试走代理
pytest tests/test_parser.py -v -s --proxy "http://127.0.0.1:7890"

# 测试单个链接走代理
pytest tests/test_parser.py::test_fetch_all -s \
  --url "https://mp.weixin.qq.com/s/xxxxx" \
  --proxy "http://user:pass@127.0.0.1:7890"

Metadata

Release files for wechat-article-parser 0.0.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wechat-article-parser 0.0.8
File Size Uploaded Provenance
wechat_article_parser-0.0.8.tar.gz 18.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for wechat-article-parser 0.0.8
File Interpreter ABI Platform
wechat_article_parser-0.0.8-py3-none-any.whl Python 3 none any Details

Total release size: 32.6 kB

Release files / wechat_article_parser-0.0.8.tar.gz

Download URL wechat_article_parser-0.0.8.tar.gz
Size 18.7 kB
Tags Source
SHA-256 checksum
How to use checksums
1a331638df0d452a9cbd4d0e25251da9350c13307305737562490d3f2d4f34bb
BLAKE2b-256 checksum
How to use checksums
e16c233315cc7b6bca29680d3e0468f9d098b8bd3f58336497bb36c6989f2ee8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release files / wechat_article_parser-0.0.8-py3-none-any.whl

Download URL wechat_article_parser-0.0.8-py3-none-any.whl
Size 13.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e652d14d8819c3bf28df830ffa02b8bed6aa4528d856cc031721d3d6b1f38893
BLAKE2b-256 checksum
How to use checksums
11127215a5a01efd41c87f762b04a4004c12f2729dc6cd4b122d2f3f73d504da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Security for wechat-article-parser 0.0.8

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page