BeClaude

weidu

New
1GitHub TrendingGeneralby DQT-bit

微读(weidu)——读 mp.weixin.qq.com 公众号文章的稳定姿势。绕开层层叠叠的反爬:Jina/WebFetch/curl 全被拦或返回验证码页。 名字寓意:「微」=微信,「读」=读得到;两个字直说"让你能读到微信公众号文章"。 方法论:PowerShell HttpWebRequest 拉原始 UTF-8 字节(避开 Invoke-WebRequest 的 UTF-8→GBK 编码污染)+ Python 双容器兜底(js_content 旧版 + content_noencode 新版沉浸式)。 当用户给出 mp.weixin.qq.com 链接、要读 / 解读 / 摘要 / 提取一手数据时使用。 触发词包括但不限于:mp.weixin.qq.com/s/ 链接(任何形式)、读一下这篇微信文章、看下这个公众号、读这个链接、解读这篇文章(链接是公众号时)、提取这个公众号文章的关键信息、摘要一下这篇微信文章、微读看一下、用微读读。 即使用户只是丢一个公众号链接没说话,也应该触发——丢链接 = 想读。 不要用于非 mp.weixin.qq.com 域名(用 WebFetch / Jina 就够);不要用于需要登录态的微信内容(公众号订阅页、付费内容);不要用于公众号视频号/图文卡片(容器结构不同)。

Summary

com)文章的稳定工具。它通过PowerShell原始字节下载和Python双容器解析,绕过微信的反爬机制,确保获取到真实的文章内容,避免验证码页、乱码或空壳问题。适用于需要解读、摘要或提取公众号文章信息的场景。

Overview

微读 · weidu | 公众号文章读取工坊

工坊规矩

微信反爬不是一面墙,是一堆陷阱。每一层(Jina、WebFetch、Invoke-WebRequest)都会"看起来工作"——返回 200、给你点东西——但内容是错的(验证码页、乱码、空壳)。只信原始字节 + 自己解码,别信任何中间层的"它帮你解码好了"。

接活:用户给的输入

  • 链接形如 https://mp.weixin.qq.com/s/<id> —— 直接读
  • 链接 + 任务:「读这个 + 摘要 / 提取观点 / 翻译 / 对比另一篇」—— 先读再做任务
  • 多个链接:批量处理,但每两次 fetch 之间 Start-Sleep -Seconds 2 防风控

班规总纲

  • 先抓原始字节,再解码。任何"看起来工作但内容错"的中间层(PowerShell Invoke-WebRequest、Jina)都不能信。
  • 双容器都试,不假设js_content 在就用,不在就找 content_noencode——不要根据公众号名字猜
  • 元数据缺失就说缺失,不编。新版沉浸式文章 nickname / ct 大概率拿不到,老实写"作者未知"。
  • chars=0 不是成功。如果两个容器都没匹配上,提取脚本必须报错退出,不能静默返回空 → 给用户假象。
  • 抓下来的 HTML 留 sha8。同一篇文章不同时间抓可能不同(小幅 A/B 测试),sha8 让你后期对比能定位差异。

Step 1:原始字节下载(PowerShell)

powershell
$url = "<wx-url>"
$out = "$env:TEMP\wx_raw.html"

$req = [System.Net.HttpWebRequest]::Create($url)
$req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
$req.Headers.Add("Accept-Language","zh-CN,zh;q=0.9")
$req.Timeout = 30000

$resp = $req.GetResponse()
$ms = New-Object System.IO.MemoryStream
$resp.GetResponseStream().CopyTo($ms)
[System.IO.File]::WriteAllBytes($out, $ms.ToArray())
$resp.Close()

"len=" + $ms.Length
"sha8=" + (Get-FileHash $out -Algorithm SHA256).Hash.Substring(0,8)

为什么必须这样Invoke-WebRequest 内部对 response body 做编码推断时,会把 UTF-8 字节按系统码页(中文 Windows = GBK / cp936)解码——所有中文字符变乱码。HttpWebRequest + WriteAllBytes 走原始字节路径,由后续 Python 按 UTF-8 解码,干净。

Step 2:判断容器类型

抓下来先看是旧版还是新版:

powershell
$h = [System.IO.File]::ReadAllText("$env:TEMP\wx_raw.html", [System.Text.Encoding]::UTF8)
"js_content present? " + $h.Contains('id="js_content"')
"content_noencode present? " + $h.Contains('content_noencode:')
类型容器典型公众号
旧版<div id="js_content">...</div>APPSO、知名科技号、传统排版
新版"沉浸式"流式文章inline JS 变量 content_noencode: '<html-string>'短内容创作者、AI 圈个人号

两个都可能同时存在——以 js_content 优先(更结构化)。

Step 3:双容器提取(Python)

python
import re, html, sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

with open(r"<path-to-html>", encoding="utf-8") as f:
    h = f.read()

def find_meta(name):
    m = re.search(r'<meta[^>]+(?:property|name)="' + name + r'"[^>]+content="([^"]*)"', h)
    return html.unescape(m.group(1)) if m else None

title = find_meta("og:title")

# 路径 A:旧版 js_content(优先)
m = re.search(r'<div[^>]*id="js_content"[^>]*>(.*?)</div>\s*<script', h, re.S)
body_html = ""

if m:
    body_html = m.group(1)
else:
    # 路径 B:新版 content_noencode JS string
    i = h.find("content_noencode:")
    if i > 0:
        i = h.find("'", i)
        j = i + 1
        buf = []
        while j < len(h):
            c = h[j]
            if c == "\\" and j + 1 < len(h):
                nx = h[j+1]
                if nx == "x" and j + 3 < len(h):
                    buf.append(chr(int(h[j+2:j+4], 16))); j += 4; continue
                if nx == "u" and j + 5 < len(h):
                    buf.append(chr(int(h[j+2:j+6], 16))); j += 6; continue
                buf.append({'n':'\n','t':'\t','r':'\r',"'":"'",'"':'"','\\':'\\','/':'/'}.get(nx, nx))
                j += 2; continue
            if c == "'":
                break
            buf.append(c); j += 1
        body_html = "".join(buf)

# 班规:chars=0 不是成功
assert body_html, "FATAL: 两个容器都没匹配上——可能是新版变体或反爬命中"

# 去标签
body = re.sub(r'<br[^>]*>', '\n', body_html)
body = re.sub(r'</p>', '\n\n', body)
body = re.sub(r'</(h[1-6]|li|blockquote|section|div)>', '\n', body)
body = re.sub(r'<style[^>]*>.*?</style>', '', body, flags=re.S)
body = re.sub(r'<script[^>]*>.*?</script>', '', body, flags=re.S)
body = re.sub(r'<[^>]+>', '', body)
body = html.unescape(body)
body = re.sub(r'\n{3,}', '\n\n', body).strip()

print(f"TITLE: {title}")
print(f"chars: {len(body)}")

元数据提取

字段出处
标题<meta property="og:title" content="...">
公众号名var nickname = htmlDecode("...")(旧版有,新版常缺)
发布时间var ct = "<unix-timestamp>"(同上)
原文 URL<meta property="og:url" content="...">

新版沉浸式文章 nickname / ct 大概率拿不到——老实写"作者未知 / 时间未知",不要编

已知陷阱

  • ❌ 只看 js_content 容器 → 新版沉浸式文章一律 0 字符正文
  • ❌ Python urllib.request 直请 → 微信检测后返回反爬页(无浏览器 UA + Accept-Language)
  • Invoke-WebRequest -OutFile → 同样存在编码推断问题
  • ❌ 假设 content_noencode 是 JSON 编码 → 实际是 JS string 转义(\x0a 不是 \n
  • ❌ 静默返回空正文 → 给用户假象,下游任务全错
  • ⚠️ 连续抓多篇 IP 易被风控 → Start-Sleep -Seconds 2 间隔
  • ⚠️ 部分文章正文段落是图片 → <img> 标签里只有图片 URL,需单独提 data-src 走 OCR 或 vision
  • ⚠️ 个别公众号会做"会员可见"折叠 → 抓到的只是开头部分,要在班规里向用户报告

实测案例

完整案例见 `examples/` 目录:

两个版本一份脚本兜底,跑通。

一句话出师证书

微信公众号文章读取的核心不是"用什么工具",是"信哪一层"。只信原始字节 + 你自己写的解码逻辑——Invoke-WebRequest 给你 GBK 乱码、Jina 给你验证码页、js_content 在新版文章里压根不存在。


发现日期:2026-06-16 · 打磨日期:2026-06-17(按鲁班 Skill v1.0 思路)

Install & Usage

1
Create the skills directory
mkdir -p .claude/skills
2
Download the skill file

Add the configuration to .claude/skills/weidu.md

3
Invoke in Claude Code
/weidu

Use Cases

读取一篇微信公众号文章,获取完整正文内容。
对给定的公众号文章链接进行摘要,提取核心观点。
批量处理多个公众号文章链接,分别提取关键信息。
解读公众号文章中的复杂观点或技术内容。
提取公众号文章中的关键数据或引用。
对比两篇公众号文章的内容差异。

Usage Examples

1

/weidu https://mp.weixin.qq.com/s/example123

2

用微读读一下这篇微信文章,然后给我摘要:https://mp.weixin.qq.com/s/example456

3

提取这个公众号文章的关键信息:https://mp.weixin.qq.com/s/example789

View source on GitHub
python

Security Audits

LicenseUnknownSourceWarnRepositoryPass

Frequently Asked Questions

What is weidu?

微读(weidu)是专门用于读取微信公众号(mp.weixin.qq.com)文章的稳定工具。它通过PowerShell原始字节下载和Python双容器解析,绕过微信的反爬机制,确保获取到真实的文章内容,避免验证码页、乱码或空壳问题。适用于需要解读、摘要或提取公众号文章信息的场景。

How to install weidu?

To install weidu: create the skills directory (mkdir -p .claude/skills), then add the config to .claude/skills/weidu.md. Finally, /weidu in Claude Code.

What is weidu best for?

weidu is a other categorized under General. It is designed for: python. Created by DQT-bit.

What can I use weidu for?

weidu is useful for: 读取一篇微信公众号文章,获取完整正文内容。; 对给定的公众号文章链接进行摘要,提取核心观点。; 批量处理多个公众号文章链接,分别提取关键信息。; 解读公众号文章中的复杂观点或技术内容。; 提取公众号文章中的关键数据或引用。; 对比两篇公众号文章的内容差异。.