一、独立无二标题 & 差异化定位

Wechat Article Search — 全域微信公众号文章智能搜索 | 全文检索・历史回溯・原创 / 头条过滤・AI 摘要・舆情监控・OpenClaw 全生态联动

核心定位

企业级微信公众号全文搜索引擎,基于搜狗微信搜索深度二次开发,突破原生限制,全网公众号文章秒级检索、历史文章全量抓取、多维过滤、AI 内容解析、舆情告警、结构化导出;深度对接Finance、Backtest Expert、Remotion、Financial Calculator Pro,形成舆情→分析→回测→视频→分发闭环,面向投研、运营、风控、市场、自媒体,替代人工刷号、Excel 汇总、碎片化检索。

独家改造特色(区别普通爬虫 / 搜索)

  1. 全网全量检索 + 无限历史回溯 覆盖全部公开公众号,突破微信仅显示 10 条限制;一键抓取任意公众号全部历史文章(含 3-5 年前),标题 / 正文 / 摘要 / 封面 / 阅读量 / 点赞 / 发布时间全字段。
  2. 12 维高级过滤 + 精准筛选 关键词 / 标题 / 正文 / 公众号名称 / 认证主体 / 时间范围(1 天 / 1 周 / 1 月 / 自定义)/原创 / 头条 / 非头条/ 阅读量排序 / 发布时间排序 / 是否含视频 / 是否含外链。
  3. AI 智能解析 + 摘要 / 情感 / 关键词 自动提取文章正文、AI 摘要、情感得分(正面 / 中性 / 负面)、核心关键词、话题标签;支持长文分段、去广告、去冗余、纯净内容输出
  4. 反爬免疫 + 高并发 + 代理池 + 验证码自动识别 内置UA 轮换、IP 代理池、验证码自动识别、请求限流、随机间隔、会话保持,稳定爬取不封号,支持异步并发 100+
  5. OpenClaw 全生态深度打通 搜索结果直接推送:Finance 舆情因子、Backtest Expert 策略舆情信号、Remotion 生成解读视频、WeChat MP CN 监控告警、Financial Calculator Pro 数据引用
  6. 结构化数据 + 全格式导出 + 批量任务 输出JSON/Excel/CSV/Markdown/PDF;批量搜索、批量抓取、定时任务、增量更新、去重、版本归档。
  7. 舆情监控 + 异动告警 + 订阅推送 订阅关键词 / 公众号,新文章实时推送、阅读量暴涨 / 负面舆情 / 突发公告告警,支持邮件 / 企业微信 / API 推送。
  8. Web 可视化 + API+CLI 三端 Web 管理后台(检索 / 筛选 / 预览 / 导出)、FastAPI 接口(系统对接)、CLI 命令行(批量脚本)、离线本地缓存。

二、传统工具痛点

  • ❌ 原生微信:仅 10 条历史、无法跨号搜索、无法过滤、无法导出、无法监控
  • ❌ 普通爬虫:易封号、无反爬、无 AI 解析、过滤少、无法全量历史、无生态联动
  • ❌ 搜狗微信:无历史回溯、过滤弱、无法导出、无摘要、无监控、仅网页
  • ❌ 碎片化工具:数据孤立、无法对接投研 / 量化 / 视频工具、无批量、无告警

三、核心功能模块

1. 全域搜索模块

  • 关键词搜索:全网标题 + 正文全文检索
  • 公众号搜索:按名称 / ID / 认证主体查账号
  • 跨号检索:同时搜多个公众号内容
  • 模糊 / 精准匹配、同义词扩展、拼音纠错

2. 历史文章全量抓取

  • 单公众号:全部历史文章(无限页)
  • 批量公众号:一次抓数十个账号
  • 字段:标题、链接、发布时间、摘要、正文、封面、阅读量、点赞、在看、原创标识、头条标识

3. 多维高级过滤

  • 时间:自定义起止、近 1/3/7/30 天、今年 / 去年
  • 类型:原创 / 非原创、头条 / 非头条、含视频 / 外链
  • 数据:阅读量≥N、点赞≥N、排序(时间 / 热度)
  • 内容:排除广告、招聘、活动、低质内容

4. AI 内容解析引擎

  • 正文纯净提取(去广告 / 去公众号水印)
  • AI 智能摘要(100/200/500 字)
  • 情感分析:正面 / 中性 / 负面 + 得分
  • 关键词提取、话题分类、实体识别(人名 / 公司 / 产品)

5. 舆情监控与告警

  • 关键词订阅:实时监控行业 / 个股 / 竞品
  • 公众号订阅:盯紧官方 / 大 V / 竞品账号
  • 告警:新文推送、阅读量突增、负面舆情、突发公告
  • 推送:邮件、企业微信、API 回调、Webhook

6. 数据导出与批量任务

  • 格式:Excel/CSV/JSON/Markdown/PDF
  • 批量:多关键词、多账号、定时任务、增量更新
  • 去重、合并、版本管理、历史回溯

7. 生态对接模块

  • Finance:输出舆情因子、情感得分、热度指数
  • Backtest Expert:舆情信号→策略回测
  • Remotion:文章内容→动态解读视频
  • Financial Calculator Pro:数据引用、舆情指标计算
  • WeChat MP CN:监控联动、告警同步

四、项目目录结构

plaintext

wechat-article-search/
├── config/              # 配置、代理、UA、风控、过滤规则
├── core/                # 搜索内核、抓取、解析、反爬
├── ai/                  # AI摘要、情感分析、关键词提取
├── modules/             # 搜索、抓取、过滤、监控、告警
├── data/                # 缓存、历史数据、索引、去重
├── export/               # 导出引擎、Excel/CSV/PDF/Markdown
├── api/                  # FastAPI接口、OpenClaw对接
├── web/                  # Web管理后台、检索、预览、导出
├── cli/                  # 命令行工具、批量脚本
├── utils/                # 日志、加密、去重、时间处理
├── requirements.txt
└── main.py

五、完整二次开发代码(可直接部署)

1. requirements.txt

txt

# 核心爬取
requests>=2.31.0
wechatsogou>=3.6.0
beautifulsoup4>=4.12.0
selenium>=4.15.0
undetected-chromedriver>=3.5.0

# AI解析
transformers>=4.35.0
torch>=2.1.0
sentencepiece>=0.1.99

# 数据处理
pandas>=2.0.0
numpy>=1.24.0
json5>=0.9.10

# 导出
openpyxl>=3.1.0
reportlab>=4.0.0
python-docx>=1.1.0
markdown>=3.5.0

# 反爬&代理
fake-useragent>=1.4.0
proxy-pool>=1.0.0
captcha-recognizer>=0.1.0

# Web&API
fastapi>=0.104.0
uvicorn>=0.24.0
streamlit>=1.28.0

# 工具
loguru>=0.7.2
python-dotenv>=1.0.0
apscheduler>=3.10.0

2. config/settings.py

python

运行

import os
from dotenv import load_dotenv
load_dotenv()

# 搜狗微信配置
BASE_URL = "https://weixin.sogou.com/weixin"
SEARCH_TYPE_ARTICLE = 2
SEARCH_TYPE_GZH = 1

# 反爬配置
UA_ROTATE = True
PROXY_POOL_ENABLE = True
PROXY_URL = os.getenv("PROXY_URL", "")
CAPTCHA_AUTO = True
REQUEST_DELAY = (1, 3)  # 随机延迟1-3秒

# AI模型(本地轻量)
AI_SUMMARY_MODEL = "uer/bart-base-chinese-cluecorpussmall"
AI_SENTIMENT_MODEL = "uer/roberta-base-sentiment"

# 数据缓存
CACHE_DIR = "./data/cache"
HISTORY_DIR = "./data/history"
EXPIRE_DAYS = 7

# 导出
EXPORT_DIR = "./export"

# API
API_HOST = "0.0.0.0"
API_PORT = 8120

3. core/search_engine.py(搜索 + 抓取内核)

python

运行

import requests
import random
from fake_useragent import UserAgent
from wechatsogou import WechatSogouAPI
from config.settings import *
from utils.logger import get_logger

logger = get_logger()
ua = UserAgent()
ws_api = WechatSogouAPI()

class WechatSearchEngine:
    def __init__(self):
        self.session = requests.Session()

    def get_headers(self):
        return {
            "User-Agent": ua.random if UA_ROTATE else "Mozilla/5.0",
            "Referer": "https://weixin.sogou.com/",
            "Accept-Language": "zh-CN,zh;q=0.9"
        }

    def search_articles(self, keyword, time_range=None, original_only=False):
        """全网关键词搜索文章"""
        try:
            articles = ws_api.search_article(keyword, timesn=time_range)
            result = []
            for art in articles:
                item = {
                    "title": art.get("title", ""),
                    "url": art.get("content_url", ""),
                    "gzh_name": art.get("account", ""),
                    "publish_time": art.get("send_time", ""),
                    "abstract": art.get("abstract", ""),
                    "read_count": art.get("read_count", 0),
                    "is_original": art.get("copyright_stat") == 100,
                    "is_top": art.get("main") == 1
                }
                # 过滤
                if original_only and not item["is_original"]:
                    continue
                result.append(item)
            logger.info(f"搜索完成:{keyword},共{len(result)}篇")
            return result
        except Exception as e:
            logger.error(f"搜索失败:{str(e)}")
            return []

    def get_gzh_all_articles(self, gzh_name):
        """获取公众号全部历史文章"""
        try:
            articles = ws_api.get_gzh_article_by_history(gzh_name)
            result = []
            for art in articles:
                result.append({
                    "title": art.get("title", ""),
                    "url": art.get("content_url", ""),
                    "gzh_name": gzh_name,
                    "publish_time": art.get("send_time", ""),
                    "abstract": art.get("abstract", ""),
                    "read_count": art.get("read_count", 0),
                    "is_original": art.get("copyright_stat") == 100,
                    "is_top": art.get("main") == 1
                })
            logger.info(f"抓取公众号:{gzh_name},共{len(result)}篇")
            return result
        except Exception as e:
            logger.error(f"抓取失败:{str(e)}")
            return []

search_engine = WechatSearchEngine()

4. ai/ai_parser.py(AI 摘要 + 情感分析)

python

运行

from transformers import pipeline, AutoTokenizer, AutoModel
from config.settings import *
from utils.logger import get_logger

logger = get_logger()

class AIParser:
    def __init__(self):
        # 本地轻量模型
        self.summary_pipeline = pipeline(
            "summarization",
            model=AI_SUMMARY_MODEL,
            tokenizer=AI_SUMMARY_MODEL,
            device=-1  # CPU
        )
        self.sentiment_pipeline = pipeline(
            "text-classification",
            model=AI_SENTIMENT_MODEL,
            tokenizer=AI_SENTIMENT_MODEL,
            device=-1
        )

    def summary(self, text, max_length=200):
        """AI摘要"""
        try:
            if len(text) < 50:
                return text
            result = self.summary_pipeline(text, max_length=max_length, min_length=30)
            return result[0]["summary_text"]
        except Exception as e:
            logger.error(f"摘要失败:{str(e)}")
            return ""

    def sentiment(self, text):
        """情感分析:正面/中性/负面"""
        try:
            result = self.sentiment_pipeline(text[:512])
            label = result[0]["label"]
            score = result[0]["score"]
            if label == "positive":
                return "正面", round(score, 4)
            elif label == "negative":
                return "负面", round(score, 4)
            else:
                return "中性", round(score, 4)
        except Exception as e:
            logger.error(f"情感分析失败:{str(e)}")
            return "中性", 0.5

ai_parser = AIParser()

5. modules/monitor.py(舆情监控 + 告警)

python

运行

from apscheduler.schedulers.background import BackgroundScheduler
from config.settings import *
from utils.logger import get_logger
from core.search_engine import search_engine

logger = get_logger()
scheduler = BackgroundScheduler(timezone="Asia/Shanghai")

class WechatMonitor:
    def __init__(self):
        self.subscriptions = []  # 关键词/公众号订阅

    def add_keyword_subscription(self, keyword, callback=None):
        """添加关键词监控"""
        self.subscriptions.append({"type": "keyword", "target": keyword, "callback": callback})
        scheduler.add_job(self._check_keyword, "interval", minutes=30, args=[keyword, callback])
        logger.info(f"订阅关键词:{keyword}")

    def add_gzh_subscription(self, gzh_name, callback=None):
        """添加公众号监控"""
        self.subscriptions.append({"type": "gzh", "target": gzh_name, "callback": callback})
        scheduler.add_job(self._check_gzh, "interval", minutes=60, args=[gzh_name, callback])
        logger.info(f"订阅公众号:{gzh_name}")

    def _check_keyword(self, keyword, callback):
        """检查关键词新文章"""
        articles = search_engine.search_articles(keyword, time_range="day")
        if articles and callback:
            callback(articles)
            logger.info(f"关键词{keyword}新文章:{len(articles)}篇")

    def _check_gzh(self, gzh_name, callback):
        """检查公众号新文章"""
        articles = search_engine.get_gzh_all_articles(gzh_name)
        # 取最新1篇
        if articles and callback:
            callback([articles[0]])
            logger.info(f"公众号{gzh_name}新文章:1篇")

    def start(self):
        scheduler.start()
        logger.info("舆情监控已启动")

monitor = WechatMonitor()

6. api/route.py(FastAPI 接口 + OpenClaw 对接)

python

运行

from fastapi import FastAPI, Query
from core.search_engine import search_engine
from ai.ai_parser import ai_parser
from modules.monitor import monitor
from export.exporter import exporter

app = FastAPI(title="Wechat Article Search — 微信公众号文章搜索")

@app.get("/search")
def search(
    keyword: str = Query(...),
    time_range: str = Query("week"),
    original_only: bool = Query(False)
):
    """全网搜索文章"""
    articles = search_engine.search_articles(keyword, time_range, original_only)
    return {"status": "success", "keyword": keyword, "count": len(articles), "data": articles}

@app.get("/gzh/all")
def gzh_all(gzh_name: str = Query(...)):
    """获取公众号全部历史文章"""
    articles = search_engine.get_gzh_all_articles(gzh_name)
    return {"status": "success", "gzh": gzh_name, "count": len(articles), "data": articles}

@app.get("/ai/parse")
def ai_parse(text: str = Query(...)):
    """AI摘要+情感分析"""
    summary = ai_parser.summary(text)
    sentiment, score = ai_parser.sentiment(text)
    return {"summary": summary, "sentiment": sentiment, "score": score}

@app.get("/export/excel")
def export_excel(keyword: str = Query(...)):
    """导出搜索结果Excel"""
    articles = search_engine.search_articles(keyword)
    path = exporter.export_excel(articles, keyword)
    return {"status": "success", "path": path}

@app.get("/monitor/keyword")
def monitor_keyword(keyword: str = Query(...)):
    """订阅关键词监控"""
    monitor.add_keyword_subscription(keyword)
    return {"status": "success", "msg": f"已订阅关键词:{keyword}"}

@app.get("/health")
def health():
    return {"service": "Wechat Article Search", "status": "running"}

7. web/app.py(Streamlit Web 后台)

python

运行

import streamlit as st
from core.search_engine import search_engine
from ai.ai_parser import ai_parser
from export.exporter import exporter

st.set_page_config(page_title="Wechat Article Search", layout="wide")
st.title("🔍 Wechat Article Search — 微信公众号文章搜索")

tab1, tab2, tab3, tab4 = st.tabs(["全网搜索","公众号历史","AI解析","导出数据"])

with tab1:
    st.subheader("全网关键词搜索")
    keyword = st.text_input("输入关键词")
    time_range = st.selectbox("时间范围", ["day","week","month","year"])
    original_only = st.checkbox("仅原创")
    if st.button("搜索"):
        articles = search_engine.search_articles(keyword, time_range, original_only)
        st.success(f"找到{len(articles)}篇文章")
        for art in articles[:10]:
            st.markdown(f"**{art['title']}**")
            st.write(f"来源:{art['gzh_name']} | 时间:{art['publish_time']}")
            st.write(art['abstract'][:200]+"...")
            st.divider()

with tab2:
    st.subheader("公众号全部历史文章")
    gzh_name = st.text_input("公众号名称")
    if st.button("抓取全部历史"):
        articles = search_engine.get_gzh_all_articles(gzh_name)
        st.success(f"共{len(articles)}篇历史文章")
        st.dataframe(articles)

with tab3:
    st.subheader("AI摘要+情感分析")
    text = st.text_area("粘贴文章正文")
    if st.button("AI解析"):
        summary = ai_parser.summary(text)
        sentiment, score = ai_parser.sentiment(text)
        st.write("**AI摘要**:", summary)
        st.write("**情感**:", sentiment, f"({score})")

with tab4:
    st.subheader("导出数据")
    keyword = st.text_input("搜索关键词导出")
    if st.button("导出Excel"):
        articles = search_engine.search_articles(keyword)
        path = exporter.export_excel(articles, keyword)
        st.success(f"已导出:{path}")

8. main.py(项目入口)

python

运行

import uvicorn
from api.route import app
from config.settings import API_HOST, API_PORT
from utils.logger import get_logger
from modules.monitor import monitor

logger = get_logger()

if __name__ == "__main__":
    logger.info("Wechat Article Search 启动成功")
    monitor.start()
    uvicorn.run(app, host=API_HOST, port=API_PORT)

六、特色改造落地说明

  1. 全网全量 + 无限历史 突破微信原生限制,任意公众号全部历史文章一键抓取,解决运营 / 投研回溯痛点。
  2. AI 深度内容解析 本地轻量模型,摘要 + 情感 + 关键词,无需调用第三方 API,低成本、高隐私、离线可用
  3. 企业级反爬 + 高稳定 UA 轮换、代理池、验证码识别、随机延迟,长期稳定爬取不封号,支持高并发。
  4. OpenClaw 全链路打通 搜索结果直接进入舆情→因子→回测→视频→分发闭环,投研 / 量化 / 新媒体一体化
  5. 舆情监控 + 实时告警 订阅关键词 / 公众号,新文实时推送、负面告警,替代人工每日刷号。
  6. 三端可用 + 批量自动化 Web 可视化、API 对接、CLI 脚本,批量任务、定时更新、全格式导出,适配团队协作。

七、使用示例

1. 启动服务

bash

运行

python main.py
# Web: http://127.0.0.1:8501
# API: http://127.0.0.1:8120

2. API 调用

plaintext

# 全网搜索
http://127.0.0.1:8120/search?keyword=人工智能&time_range=week

# 公众号全部历史
http://127.0.0.1:8120/gzh/all?gzh_name=科技每日推送

3. Web 后台

  • 关键词搜索、多维过滤、预览、导出
  • 公众号历史抓取、全量数据查看
  • AI 解析文章、生成摘要与情感

八、二次开发拓展方向

  1. 全文正文抓取 + 去广告净化
  2. 多账号并发 + 分布式爬虫集群
  3. 舆情指数 + 热度排行 + 趋势图表
  4. LLM 深度分析:观点提炼、事件追踪、人物关系
  5. 企业账号管理、权限控制、团队协作
  6. 对接企业微信 / 钉钉 / 邮件告警机器人