搜狗微信点选验证的会话保持与 Cookie 续期实战

简介: 搜狗微信点选验证的会话保持与 Cookie 续期实战

搜狗微信(weixin.sogou.com)是公众号文章监测的常用入口,信任状态挂在 Cookie 上。过了点选验证码之后,SNUID、SUV 这类凭证有时效,过期就重新弹验证。核心做法是 requests.Session 养长寿命会话、按实效提前续期、尽量别掉回验证那步。下面以代码为主,叙述从简。

  1. 会话与续期核心
    ```from future import annotations

import logging
import time
from dataclasses import dataclass, field
from typing import Optional

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

logger = logging.getLogger("sogou_weixin")

@dataclass
class CrawlerConfig:
base_url: str = "https://weixin.sogou.com"
search_path: str = "/weixin"
proxy: Optional[str] = None # "http://user:pass@proxy.yiniu.com:port"
max_retries: int = 3
timeout: float = 10.0
cookie_ttl: int = 600
ua_pool: list[str] = field(default_factory=list)

class SogouSession:
def init(self, config: CrawlerConfig) -> None:
self.config = config
self.session = self._build_session()
self.cookie_issued_at: float = 0.0

def _build_session(self) -> requests.Session:
    session = requests.Session()
    retry = Retry(total=self.config.max_retries, backoff_factor=0.5,
                  status_forcelist=[429, 500, 502, 503, 504])
    session.mount("https://", HTTPAdapter(max_retries=retry))
    if self.config.proxy:
        session.proxies.update({"https": self.config.proxy})
    ua = self.config.ua_pool[0] if self.config.ua_pool else (
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
        "(KHTML, like Gecko) Chrome/124.0 Safari/537.36")
    session.headers.update({"User-Agent": ua, "Accept-Language": "zh-CN,zh;q=0.9"})
    return session

def ensure_session(self) -> None:
    if not self.session.cookies or \
       time.time() - self.cookie_issued_at > self.config.cookie_ttl:
        self._refresh()

def _refresh(self) -> None:
    try:
        resp = self.session.get(self.config.base_url + self.config.search_path,
                                params={"type": 2, "query": "测试"},
                                timeout=self.config.timeout)
        resp.raise_for_status()
        if self._is_captcha_page(resp.text):
            logger.warning("续期被弹验证码,需重新过验证")
            self._solve_captcha()
        self.cookie_issued_at = time.time()
        logger.info("续期成功,Cookie 数量=%d", len(self.session.cookies))
    except requests.RequestException as exc:
        logger.warning("续期失败:%s", exc)
        raise

def _is_captcha_page(self, html: str) -> bool:
    return "请输入验证码" in html or "antispider" in html

def _solve_captcha(self) -> None:
    raise NotImplementedError("接入点选验证码识别服务")

def fetch(self, query: str, page: int = 1) -> str:
    self.ensure_session()
    resp = self.session.get(self.config.base_url + self.config.search_path,
                            params={"type": 2, "query": query, "page": page},
                            timeout=self.config.timeout)
    resp.raise_for_status()
    return resp.text

续期阈值别拍脑袋设。先空跑看第几分钟被弹,那个点减一两分钟就是安全线。实测 SNUID 二十分钟出头松动,所以 cookie_ttl 设 600 秒留缓冲。
2. 返回内容校验,防静默失效
Cookie 还在但信任没了很常见,返回页看着正常实则是验证页。fetch 之后必须校验。
```import re

RESULT_ITEM_RE = re.compile(r'class="txt-box"')      # 正常结果条目特征
CAPTCHA_HINT_RE = re.compile(r"请输入验证码|antispider")

def validate_result(html: str) -> bool:
    """True 表示页面可信:含正常结果结构且无非验证提示。"""
    if CAPTCHA_HINT_RE.search(html):
        return False
    return bool(RESULT_ITEM_RE.search(html))

命中异常就 session.cookies.clear(),下一轮 ensure_session 强制重握手,代价只是多一次首页请求。

  1. UA 池与请求节奏
    别用默认 UA,准备几个轮换,翻页之间加随机休眠。
    ```import random

UA_POOL = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/124.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 "
"(KHTML, like Gecko) Version/17.0 Safari/605.1.15",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/123.0 Safari/537.36",
]

def pick_ua() -> str:
return random.choice(UA_POOL)

def human_sleep() -> None:
time.sleep(random.uniform(1.5, 4.0))


CrawlerConfig.ua_pool 填上 UA_POOL,_build_session 会随机取一个;每次 human_sleep() 后再翻页。
4. 多会话 Cookie 池
大批量关键词用单会话扛不住,起一组预热会话并行。
```from threading import Lock

class SogouSessionPool:
    def __init__(self, config: CrawlerConfig, size: int = 4) -> None:
        self.config = config
        self._lock = Lock()
        self._pool: list[SogouSession] = []
        for _ in range(size):
            s = SogouSession(config)
            s._refresh()          # 启动即握手预热
            self._pool.append(s)

    def acquire(self) -> SogouSession:
        with self._lock:
            s = self._pool.pop()
        s.ensure_session()
        if not validate_result(s.fetch("测试")):
            s.session.cookies.clear()
            s._refresh()
        return s

    def release(self, s: SogouSession) -> None:
        with self._lock:
            self._pool.append(s)

被弹验证码的会话移出池子走 _solve_captcha,解完放回,解不开丢弃换出口重建。

  1. 代理与出口切换
    搜狗看出口 IP 的稳定和干净。亿牛云的企业级代理支持独享 IP 与会话保持,同一任务绑定固定出口,续期时 IP 不变,验证码触发率更低。配置就是 CrawlerConfig 里那行 proxy,账号域名端口填进去即可,按请求计费对平时静默、偶尔爆发的采集也合适。
    出口断了换 IP 再握手:
    ```def rotate_proxy(config: CrawlerConfig, new_proxy: str) -> None:
    config.proxy = new_proxy # 新出口,如亿牛云切换接口返回

    之后用新 config 重建 SogouSession 即生效

    ```

  2. 验证码钩子示例
    _solve_captcha 真实环境接打码平台或自研模型,这里给个签名示例。
    ```
    from dataclasses import dataclass

@dataclass
class ClickPoint:
x: int
y: int

def _solve_captcha(self) -> None:

# 1. 拉取验证图片与提示文字
# 2. 识别点击序列(模型 / 打码平台)
points: list[ClickPoint] = recognize(self.session)
# 3. 按坐标回提交接口
submit(self.session, points)
self.cookie_issued_at = time.time()

7. 完整调用
```def parse(html: str) -> None:
    """从结果页抽取文章条目,按业务入库。"""
    # ...

def main() -> None:
    config = CrawlerConfig(proxy="http://user:pass@proxy.yiniu.com:port",
                           ua_pool=UA_POOL)
    pool = SogouSessionPool(config, size=4)
    keywords = ["双减政策", "研学旅行", "课后服务"]
    for kw in keywords:
        s = pool.acquire()
        try:
            for page in range(1, 11):
                html = s.fetch(kw, page)
                if not validate_result(html):
                    s.session.cookies.clear()
                    s._refresh()
                    continue
                parse(html)
                human_sleep()
        finally:
            pool.release(s)

if __name__ == "__main__":
    main()

骨架就三件事:Session 养长寿命会话,按实效提前续期,稳定干净的高匿代理守住出口。续期和返回校验做扎实,验证码求解当兜底,采集就能稳稳跑完一轮。

相关文章
|
6天前
|
云安全 人工智能 运维
阿里云联动百位企业安全专家,共识Agent防御最佳实践
当Agent成为新员工,你的安全边界在哪里?
1908 5
阿里云联动百位企业安全专家,共识Agent防御最佳实践
|
4天前
|
存储 人工智能 关系型数据库
阿里云AI产品与云产品最新组合套餐:Token Plan、AI coding及云服务器和建站等组合优惠价
阿里云推出全新“算力+模型+应用”一站式云与AI组合套餐活动,覆盖从个人开发者到中大型企业的全场景需求。核心亮点为分三档定价的Token Plan订阅服务,支持Qwen3.8-Max-Preview大模型调用,错峰时段最低可享0.2折优惠。活动同步推出AI Coding、智能体部署、云电脑托管、0代码建站等十余类场景化组合,搭配99元/年的普惠云服务器、88元/年的入门数据库等经典特惠产品,还为企业提供1V1定制化AI转型方案,大幅降低了不同用户群体拥抱AI的技术门槛与采购成本。
636 110
|
14天前
|
人工智能 JSON 安全
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
阿里云AI安全产品联动防御Fastjson攻击
2520 13
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
|
14天前
|
人工智能 自然语言处理 数据挖掘
Qwen3.8-Max-Preview深度全解析:2.4万亿参数旗舰MoE模型+Token Plan限时优惠完整落地指南
2026年7月,全新旗舰级混合专家大模型Qwen3.8-Max-Preview正式开放抢先体验,作为通义千问Qwen3系列规格最高、综合推理能力顶尖的新一代模型,该模型总参数量达到2.4万亿(2.4T),是当前线上可调用的原生多模态旗舰模型,综合推理水准对标海外顶级Fable 5模型,在复杂工程开发、长文档深度分析、多步骤智能体自治、跨境多语言创作、海量数据挖掘五大高难度业务场景实现跨越式性能提升。
1378 2
|
12天前
|
人工智能 前端开发 Linux
Codex 桌面版安装 + CC Switch 接入第三方 API 完整教程(2026 最新)
2026最新教程:手把手教你安装Codex桌面版,通过CC Switch v3.17.0一键接入Fenno等国产API(兼容OpenAI Responses格式),跳过账号登录,完整启用代码审查、多步任务与上下文感知功能。零基础友好,全程图文实操。(239字)
1285 2
|
16天前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
1413 54
|
12天前
|
自然语言处理 测试技术 API
通义千问Qwen3.8-Max-Preview全功能解析:2.4万亿参数旗舰模型深度使用指南
在大模型技术持续迭代的当下,通义千问推出的Qwen3.8-Max-Preview作为新一代旗舰预览版模型,凭借2.4万亿参数的超大规模、多模态融合能力与全场景适配特性,成为开发者与企业用户探索AI应用的核心工具。该模型采用稀疏混合专家(MoE)架构,是通义千问首个突破万亿参数的多模态模型,可同时处理文本、图像、视频与文档等多种数据形态,在全栈代码开发、复杂逻辑推理、长文档分析与多智能体协作等场景实现跨越式升级。本文将全面拆解Qwen3.8-Max-Preview的核心功能,详解API调用流程与配置方法,覆盖多场景实战技巧,帮助用户快速掌握这款旗舰模型的使用方法,充分释放其性能潜力。
664 2