入门级反爬看 UA 和 IP进阶反爬看验证码、参数加密、行为风控。这一篇讲目前最常见的三种进阶反爬手段怎么应对。一、滑动验证码滑块验证码是目前应用最广的人机验证方式常见的产品有产品使用方难度极验 Geetest知乎、B站、斗鱼⭐⭐⭐ 标准版阿里云滑块淘宝、1688⭐⭐⭐⭐腾讯防水墙微信、QQ⭐⭐⭐滑动验证的校验逻辑用户操作 拖动滑块 → 前端记录轨迹数据坐标、速度、加速度 ↓ 服务器校验 ① 轨迹是否像人类操作不是直线 ② 拖动的距离是否正确缺口位置 ③ 浏览器环境特征WebDriver、Canvas指纹方案一Selenium 模拟拖动fromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriverimportActionChainsimporttime driverwebdriver.Chrome()driver.get(https://example.com/login)# 等待滑块出现sliderdriver.find_element(By.CLASS_NAME,geetest_slider_button)# 模拟人类拖动关键不是匀速直线actionActionChains(driver)action.click_and_hold(slider).perform()# 分段拖动先慢后快再慢模拟人类track[(0,0),# 起始(50,3),# 开始移动轻微上下抖动(100,-2),(150,5),(200,1),(230,-3),(250,0),# 接近目标放慢(258,0),(262,0),# 到达]forx,yintrack:action.move_by_offset(x,y).perform()time.sleep(0.01)# 每步间隔10msaction.release().perform()time.sleep(2)方案二机器学习识别缺口位置importcv2importnumpyasnpdeffind_gap_position(bg_image_path,slider_image_path):识别滑块缺口位置像素坐标# 读取背景图和滑块图bgcv2.imread(bg_image_path,0)# 灰度图slidercv2.imread(slider_image_path,0)# 模板匹配找到滑块在背景中的位置resultcv2.matchTemplate(bg,slider,cv2.TM_CCOEFF_NORMED)_,_,_,max_loccv2.minMaxLoc(result)# 缺口左上角坐标x,ymax_locreturnx# 使用gap_xfind_gap_position(bg.jpg,slider.png)print(f缺口位置在{gap_x}像素处)方案三直接用打码平台省事国内主流的打码平台都支持滑块验证码识别价格通常 1-3 分钱/次# 以某打码平台为例importrequestsdefsolve_slider_captcha(bg_url,slider_url):调用打码平台识别滑块api_keyyour_api_keydata{key:api_key,method:slide_captcha,bg:bg_url,# 背景图URLslider:slider_url# 滑块图URL}resprequests.post(http://api.damaplatform.com/solve,jsondata)resultresp.json()ifresult[success]:# 返回缺口 x 坐标直接传给浏览器returnresult[data][x]else:print(f识别失败:{result.get(message)})returnNone建议免费折腾的时间成本往往比付费高。如果只是需要采集数据打码平台几块钱就能解决大部分验证码。二、请求参数加密越来越多的 App 和 Web 端对请求参数做了加密直接抓包看到的是一堆乱码。1. 常见加密方式① 参数签名params secret → MD5/SHA256 → sign 服务端用同样的方式算一遍不一致就拒绝 ② 请求体加密整个 body 用 AES/RSA 加密 服务端解密后再处理 ③ 请求头自定义x-timestamp、x-nonce、x-sign 防重放攻击2. 逆向找到加密代码# 通过抓包定位加密入口# 方法在 Fiddler/Charles 中找加密参数# 然后在 JS 代码中搜索关键字# 常见的搜索关键词search_keywords[sign,signature,token,encrypt,encode,md5,sha256,aes,rsa,nonce,timestamp,]3. 用 Python 复现加密逻辑importhashlibimporttimeimportrandomimportstringdefgenerate_sign(params,secretyour_secret_key):复现 App 的签名算法# 1. 参数按字典序排序sorted_keyssorted(params.keys())# 2. 拼接成字符串raw_parts[]forkinsorted_keys:raw_parts.append(f{k}{params[k]})# 3. 拼接密钥raw_str.join(raw_parts)secret# 4. MD5 加密signhashlib.md5(raw_str.encode()).hexdigest()returnsigndefgenerate_nonce(length10):生成随机字符串防重放return.join(random.choices(string.ascii_lettersstring.digits,klength))defmake_request(url,params):带签名的请求params[timestamp]int(time.time())params[nonce]generate_nonce()params[sign]generate_sign(params)resprequests.get(url,paramsparams)returnresp.json()4. 逆向工具推荐工具用途难度Fiddler FiddlerScript打断点调试 JS⭐⭐Chrome DevTools在 Sources 中搜索加密函数⭐⭐AST抽象语法树反混淆加密 JS 代码⭐⭐⭐⭐PyExecJS用 Python 执行 JS 代码⭐⭐⭐JSDom模拟浏览器环境执行 JS⭐⭐⭐最实用的方法用 PyExecJS 直接调用网站的加密 JSimportexecjsimportrequests# 加载网站的加密 JS 文件从 Chrome Sources 中复制出来withopen(encrypt.js,r,encodingutf-8)asf:js_codef.read()# 编译 JSctxexecjs.compile(js_code)# 调用 JS 中的加密函数params{username:test,password:123456}signctx.call(encryptSign,params)print(f加密签名:{sign})三、风控绕过——不要像机器人一样访问现在的大厂淘宝、抖音、美团都有风控系统技术上的反爬只是一个层面行为层面的风控往往更敏感。1. 风控系统会检测什么① 访问模式 ❌ 每隔 3 秒整点访问 → 像定时任务 ✅ 随机间隔 2-5 秒 → 像人类 ② 浏览路径 ❌ 直接访问目标页面 → 不经过首页 ✅ 先首页 → 列表页 → 详情页 → 像正常用户 ③ 鼠标/手势 ❌ 无鼠标轨迹 → Selenium 特征 ✅ 有曲线移动 → 人类行为 ④ 账户行为 ❌ 一个账号每天爬 10 万次 ✅ 多个账号分散爬2. 模拟人类行为importtimeimportrandomfromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy driverwebdriver.Chrome()defhuman_like_scroll(driver):模拟人类滚动页面for_inrange(random.randint(3,6)):scroll_distancerandom.randint(200,500)driver.execute_script(fwindow.scrollBy(0,{scroll_distance});)time.sleep(random.uniform(0.5,1.5))defhuman_like_click(driver,element):模拟人类点击# 先移动鼠标到元素actionwebdriver.ActionChains(driver)action.move_to_element(element).perform()time.sleep(random.uniform(0.2,0.8))element.click()defrandom_delay():随机延时避免固定间隔time.sleep(random.uniform(1.5,4.5))# 使用driver.get(https://example.com)time.sleep(random.uniform(2,4))# 模拟页面加载延迟# 模拟人类浏览human_like_scroll(driver)human_like_click(driver,driver.find_element(By.LINK_TEXT,下一页))random_delay()3. 多账号轮换importitertoolsclassAccountPool:账号池轮流使用def__init__(self):self.accounts[{phone:1380001,token:token_a},{phone:1380002,token:token_b},{phone:1380003,token:token_c},]self.poolitertools.cycle(self.accounts)defget_account(self):returnnext(self.pool)defmark_banned(self,account):print(f账号{account[phone]}被封移除)self.accounts.remove(account)poolAccountPool()foriinrange(100):accountpool.get_account()headers{Authorization:fBearer{account[token]}}resprequests.get(https://api.example.com/data,headersheaders)# ...time.sleep(random.uniform(2,5))4. 风控降级策略当爬虫触发风控时不要硬刚降低采集频率classAdaptiveCrawler:自适应降级爬虫def__init__(self,initial_delay1):self.delayinitial_delay self.min_delay0.5self.max_delay30self.success_count0self.fail_count0defrequest(self,url):自适应请求time.sleep(self.delay)resprequests.get(url,headersheaders)ifresp.status_code200:self.success_count1self.fail_count0# 连续成功 10 次适当加速ifself.success_count10:self.delaymax(self.min_delay,self.delay*0.8)self.success_count0elifresp.status_codein[403,429]:self.fail_count1self.success_count0# 触发风控减速self.delaymin(self.max_delay,self.delay*2)print(f触发风控降级到{self.delay}s 间隔)returnresp crawlerAdaptiveCrawler(initial_delay2)datacrawler.request(https://example.com/api)四、反爬对抗的真正原则反爬对抗不是技术的较量而是成本和收益的博弈 网站为什么反爬 怕你影响服务器性能、怕数据被竞对采集 如果你 爬得慢、像个人、不是大规模批量 大多数网站根本就不管你实用的反反爬策略优先级先试试不加任何伪装 → 被拦了再加UA → 被拦了加延时 → 被拦了换代理IP → 被拦了处理验证码 → 被拦了逆向加密参数 → 被拦了模拟行为风控从最简单的方法开始够用就行不要一上来就搞签名逆向和机器学习。 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。