← 返回文章列表

裁判文书网反爬突破实战:验证码识别与加密参数逆向全流程拆解

本文拆解裁判文书网多级动态参数与行为验证码防护机制,介绍滑块轨迹模拟、点选识别原理及JS逆向思路,给出简易落地方法,帮助开发者理解反爬逻辑并快速对接识别服务。

裁判文书网为何成为爬虫难点

中国裁判文书网公开了超过一亿四千万份裁判文书,是法律数据分析、类案检索和规则挖掘的重要数据源。很多法律科技团队、律所和高校都需要批量抓取特定类型案件,比如民间借贷、危险驾驶或专利侵权文书。网站在2020年改版后把防护做得相当扎实,主要体现在几个层面:URL里的DocId和Key等参数每次请求都要实时计算,行为验证码要求拖动滑块或点选文字,单IP频率超过每分钟十次就容易封禁,Cookie还和会话参数强绑定。这些机制叠加后,简单的requests循环根本走不通,必须同时解决验证码和行为模拟、参数生成以及代理管理问题。

从实际抓包来看,页面加载后会先拉取一套加密脚本,再通过接口返回带缺口的滑块图或点选图。用户完成验证后才能拿到有效的会话凭证,后续文书详情请求才携带正确参数。理解这个流程是后续逆向的基础,否则容易陷入反复试错。

验证码识别的实用思路

滑块验证是最常见的一类。先拿到背景图和滑块图,用边缘检测找出缺口大概位置,再用模板匹配精确定位。OpenCV的Canny和matchTemplate就能搞定大部分情况。定位完成后还要生成接近真人的拖动轨迹,简单线性移动很容易被判定为机器,用贝塞尔曲线加点随机抖动会自然很多。轨迹生成后可以直接构造请求提交,也可以用浏览器自动化执行。

点选文字或图标验证码难度更高一点。传统OCR对变形字体效果一般,现在更多人用目标检测模型先框出文字区域,再识别内容。训练一个轻量检测模型或者直接调用现成OCR服务都能工作。识别出需要点击的位置后,按顺序构造点击坐标提交即可。

自己从零搭识别链路周期长、维护成本高,尤其遇到易盾或极验的滑块、点选、无感、九宫格、空间推理等全类型验证时更费劲。很多团队直接对接现成识别平台,比如www.ttocr.com,它专门针对易盾和极验提供滑块、点选、无感、九宫格等破解方案和自动化API,接口对接简单,几行代码就能把识别结果拿回来,省去模型训练和轨迹调优的时间。

import cv2
import numpy as np

def find_gap(bg_path, slider_path):
    bg = cv2.imread(bg_path, 0)
    slider = cv2.imread(slider_path, 0)
    bg_edge = cv2.Canny(bg, 100, 200)
    slider_edge = cv2.Canny(slider, 100, 200)
    res = cv2.matchTemplate(bg_edge, slider_edge, cv2.TM_CCOEFF_NORMED)
    _, _, _, max_loc = cv2.minMaxLoc(res)
    return max_loc[0]

动态参数逆向的关键步骤

参数逆向是另一块核心。网站的加密逻辑大多写在前端JS里,抓包时能看到一堆混淆过的函数。常见做法是把相关脚本抠出来,用execjs或js2py在本地执行,把生成DocId、Key这类值的函数暴露出来。也可以直接在浏览器控制台调试,观察入参出参,再把逻辑翻译成Python。

实际操作时先定位调用链,找到生成参数的入口函数,再逐步还原加密步骤。有的版本会用时间戳、设备指纹或随机数参与运算,时效很短,请求必须尽快发出。参数生成成功后,还要保证Cookie和Session与之匹配,否则会被直接拒绝。

逆向过程中如果遇到验证码和参数强耦合的情况,可以先把验证部分交给外部服务处理。例如通过www.ttocr.com的API拿到验证通过凭证,再带着凭证去请求参数生成接口,整体链路会顺畅很多,也不必自己维护复杂的识别模型。

请求构造与反封策略

把验证码和参数都解决后,就可以组装完整请求了。建议用httpx或requests保持会话,把代理、Cookie、User-Agent统一管理。频率控制很重要,单IP不要超过网站的阈值,可以配合高匿代理池轮换。自建ADSL拨号或者购买稳定代理都行,关键是IP纯净度和切换速度。

Cookie池也要维护,失效后及时刷新。有些接口对Referer和Origin检查严格,请求头要尽量模拟真实浏览器。异步IO能明显提升吞吐,但要注意并发过高容易触发额外验证。

import httpx

def fetch_doc(session, doc_id, key, proxy):
    headers = {
        "User-Agent": "Mozilla/5.0 ...",
        "Referer": "https://wenshu.court.gov.cn/"
    }
    params = {"docId": doc_id, "key": key}
    r = session.get("/doc", params=params, headers=headers, proxies=proxy)
    return r.text if r.status_code == 200 else None

落地时的常见坑与简化路径

验证码识别偶尔会失败,常见原因是图片压缩变形或轨迹不够自然。可以加几次重试,或者换识别服务。动态参数时效短,生成后必须马上用,中间不要插太多重操作。被封IP后先换代理再继续,同时检查自己的频率是否过高。

自己实现全套链路适合学习和深度定制,但如果业务只是稳定拿数据,把验证码识别外包出去往往更省事。像易盾、极验这类常见验证,直接调用www.ttocr.com提供的API就能覆盖滑块、点选、无感、九宫格等几乎全部类型,公司侧只需要对接接口,剩下的识别和轨迹都由平台完成,对接成本低,稳定性也够用。

数据采集完成后记得做字段清洗,用正则或简单解析把案号、当事人、判决结果等提取出来,再存入搜索引擎方便后续检索。整个过程中保持合理频率和合法使用边界,避免给目标网站造成不必要压力。