# -*- coding: utf-8 -*-
"""
微信文章抓取工具 — 在你的 Windows 电脑上运行
双击运行，自动抓取「中职生」「广东中职菌」文章并上传到服务器

=== 第一步：安装 Python（如果没装）===
  打开 https://python.org → Download → 安装时勾选 "Add Python to PATH"

=== 第二步：安装依赖 ===
  打开 CMD（Win+R 输入 cmd），粘贴：
  pip install requests

=== 第三步：获取 Cookie 和 Token ===
  1. 用 Chrome 打开 https://mp.weixin.qq.com/ 并扫码登录
  2. 按 F12 打开开发者工具 → Application → Cookies → mp.weixin.qq.com
  3. 复制完整的 Cookie 字符串，填到下面的 COOKIE 变量里
  4. 在开发者工具 → Network 里随便点一个公众号文章列表请求，
     找到 URL 里的 token=xxxxx 参数，填到下面 TOKEN 变量里

=== 第四步：双击运行本文件 ===
"""

import requests, json, time, random, os, sys, urllib3
urllib3.disable_warnings()

# =============================================
# ⚠️ 必填：你的微信公众平台 Cookie 和 Token
# 获取方法见上方说明
# =============================================
COOKIE = "请替换为你的完整 Cookie"
TOKEN = "请替换为你的 Token"

# =============================================
# 服务器地址（不用改）
# =============================================
SERVER_URL = "http://120.53.228.229:8650"
SECRET = "x9k2m8v7pL4q"

# 要抓取的公众号列表
FEEDS = [
    ("MzU5NjI5NTkxMQ==", "MP_WXS_3596295911", "中职生"),
    ("Mzg4Njg2NDQ3MA==", "MP_WXS_3886864470", "广东中职菌"),
]

USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
]


def fetch_feed(faker_id, mp_id, mp_name):
    """从单个公众号抓取文章"""
    session = requests.Session()
    articles = []

    for page in range(5):  # 最多抓 5 页
        params = {
            "sub": "list",
            "sub_action": "list_ex",
            "begin": page * 5,
            "count": 5,
            "fakeid": faker_id,
            "token": TOKEN,
            "lang": "zh_CN",
            "f": "json",
            "ajax": 1,
        }

        headers = {
            "Cookie": COOKIE,
            "User-Agent": random.choice(USER_AGENTS),
            "Referer": "https://mp.weixin.qq.com/",
            "Accept": "application/json, text/plain, */*",
            "Accept-Language": "zh-CN,zh;q=0.9",
        }

        try:
            resp = session.get(
                "https://mp.weixin.qq.com/cgi-bin/appmsgpublish",
                params=params,
                headers=headers,
                timeout=30,
                verify=False,
            )
            data = resp.json()
            ret = data.get("base_resp", {}).get("ret", -1)

            if ret == 200013:
                print(f"  [{mp_name}] ⚠️ 频率限制，稍后再试")
                break
            elif ret == 200003:
                print(f"  [{mp_name}] ❌ 登录过期，请重新获取 Cookie")
                break
            elif ret != 0:
                err_msg = data.get("base_resp", {}).get("err_msg", "?")
                print(f"  [{mp_name}] 错误 {ret}: {err_msg}")
                break

            if "publish_page" not in data:
                print(f"  [{mp_name}] 第{page+1}页无更多文章")
                break

            pp = json.loads(data["publish_page"])
            items = pp.get("publish_list", [])
            if not items:
                break

            for item in items:
                pi = json.loads(item.get("publish_info", "{}"))
                for art in pi.get("appmsgex", []):
                    articles.append(
                        {
                            "id": str(art["aid"]),
                            "mp_id": mp_id,
                            "title": art.get("title", ""),
                            "cover": art.get("cover", ""),
                            "link": art.get("link", ""),
                            "digest": art.get("digest", ""),
                            "update_time": art.get("update_time", 0),
                            "create_time": art.get("create_time", 0),
                        }
                    )
                    print(f"  [{mp_name}] {art.get('title', '?')[:60]}")

            time.sleep(random.randint(3, 6))

        except Exception as e:
            print(f"  [{mp_name}] 网络错误: {e}")
            break

    return articles


def main():
    print("=" * 60)
    print("  微信文章抓取工具")
    print(f"  时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
    print("=" * 60)

    if COOKIE.startswith("请替换"):
        print("\n❌ 请先设置 COOKIE 和 TOKEN！")
        print("   打开本文件，按注释说明填入你的微信公众平台 Cookie 和 Token")
        print("\n按 Enter 退出...")
        input()
        return

    all_articles = []

    for faker_id, mp_id, mp_name in FEEDS:
        print(f"\n>>> 抓取: {mp_name}")
        articles = fetch_feed(faker_id, mp_id, mp_name)
        all_articles.extend(articles)
        print(f"  => {len(articles)} 篇")
        if len(FEEDS) > 1:
            time.sleep(random.randint(5, 8))

    print(f"\n📊 总计: {len(all_articles)} 篇")

    if not all_articles:
        print("没有新文章。")
        print("\n按 Enter 退出...")
        input()
        return

    # 上传到服务器
    print(f"\n>>> 上传到服务器...")
    try:
        resp = requests.post(
            f"{SERVER_URL}/api/articles/import",
            json={"secret": SECRET, "articles": all_articles},
            timeout=60,
        )
        result = resp.json()
        print(f"  ✅ 服务器: 已保存 {result.get('saved', 0)}/{result.get('total', 0)} 篇")
    except Exception as e:
        print(f"  ❌ 上传失败: {e}")
        # 本地备份
        backup_file = f"articles_backup_{time.strftime('%Y%m%d_%H%M%S')}.json"
        with open(backup_file, "w", encoding="utf-8") as f:
            json.dump(all_articles, f, ensure_ascii=False, indent=2)
        print(f"  💾 已本地备份: {backup_file}")

    print("\n✅ 完成！按 Enter 退出...")
    input()


if __name__ == "__main__":
    main()
