攻克滑动拼图反爬:Python 高效爬取网页图片实战案例

一、滑动拼图反爬核心原理剖析

在编写代码前,我们必须先理解滑动拼图验证码的工作机制,这是精准破解的关键:

  1. 前端渲染逻辑 :网站加载验证码时,会生成两张图片 ------完整背景图带缺口的滑块图,缺口位置随机生成;
  2. 验证规则:用户需要用鼠标拖动滑块,精准对齐背景图的缺口,前端会记录滑动轨迹、速度、停留时间等行为数据;
  3. 反爬检测点 :单纯的机械滑动会被识别为机器行为,网站会校验滑动轨迹是否拟人滑块位置是否精准请求参数是否合法三大核心指标;
  4. 验证流程:拖动滑块→前端校验位置→服务器验证通过→解除反爬限制→开放数据访问。

传统爬虫无法模拟拟人滑动和缺口识别,这也是滑动拼图能有效拦截自动化程序的核心原因。

二、实战环境搭建与依赖库安装

本次实战基于 Python 3.8 + 版本,核心使用Selenium 模拟浏览器操作、OpenCV 识别图片缺口、requests爬取目标图片,同时搭配 ChromeDriver 实现浏览器驱动。

1. 核心依赖库安装

打开命令行执行以下安装命令:

bash

运行

plain 复制代码
# 模拟浏览器操作
pip install selenium==4.15.0
# 图片处理与缺口识别
pip install opencv-python==4.8.0
# 网络请求与随机数生成
pip install requests numpy random

2. ChromeDriver 配置

  1. 查看本地 Chrome 浏览器版本,下载对应版本的 ChromeDriver;
  2. 将 ChromeDriver.exe 放置在 Python 根目录,或在代码中指定驱动路径。

注意:建议使用 Chrome 110 + 版本,保证驱动兼容性。

三、整体实现思路

本次实战分为五大核心步骤,形成闭环解决方案:

  1. 初始化浏览器,访问目标网站,加载滑动拼图验证码;
  2. 截取验证码背景图和滑块图,保存到本地;
  3. 基于 OpenCV 模板匹配算法,识别缺口的横向坐标;
  4. 生成拟人滑动轨迹,模拟鼠标拖动滑块完成验证;
  5. 验证通过后,定位网页图片元素,批量高效爬取并保存图片。

四、完整代码实现与分步解析

步骤 1:初始化浏览器与访问目标页面

首先封装浏览器初始化函数,关闭 Chrome 的自动化检测特征,避免被网站识别为爬虫。

python

运行

plain 复制代码
import cv2
import numpy as np
import random
import time
import requests
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import os

# 创建图片保存文件夹
if not os.path.exists("captcha_img"):
    os.mkdir("captcha_img")
if not os.path.exists("target_imgs"):
    os.mkdir("target_imgs")

def init_browser():
    """初始化Chrome浏览器,规避反爬检测"""
    chrome_options = Options()
    # 关闭自动化提示
    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
    chrome_options.add_experimental_option('useAutomationExtension', False)
    # 禁用图片加载(可选,提升速度)
    # chrome_options.add_argument('--blink-settings=imagesEnabled=false')
    # 初始化驱动
    driver = webdriver.Chrome(options=chrome_options)
    # 修改浏览器特征,隐藏webdriver属性
    driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
        'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
    })
    driver.maximize_window()
    return driver

# 初始化浏览器并访问目标网站
driver = init_browser()
# 替换为你要爬取的带滑动拼图验证的网站
target_url = "https://www.test-spider.com/slider-captcha"
driver.get(target_url)
time.sleep(2)

步骤 2:截取验证码图片

通过 Selenium 定位背景图和滑块元素,截取图片并保存,为缺口识别做准备。

python

运行

plain 复制代码
def get_captcha_img(driver):
    """获取滑动拼图的背景图和滑块图"""
    # 定位背景图和滑块元素(根据实际网页修改选择器)
    bg_img = driver.find_element(By.CLASS_NAME, "captcha-bg")
    slider_img = driver.find_element(By.CLASS_NAME, "captcha-slider")
    
    # 截取图片
    bg_img.screenshot("captcha_img/bg.png")
    slider_img.screenshot("captcha_img/slider.png")
    time.sleep(1)
    return "captcha_img/bg.png", "captcha_img/slider.png"

# 获取验证码图片
bg_path, slider_path = get_captcha_img(driver)

步骤 3:OpenCV 识别缺口坐标

这是核心步骤!使用 OpenCV 的模板匹配算法,将滑块图与背景图对比,精准计算缺口的横向偏移量。

python

运行

plain 复制代码
def get_gap_position(bg_path, slider_path):
    """识别缺口位置,返回横向偏移坐标"""
    # 读取图片
    bg = cv2.imread(bg_path, 0)
    slider = cv2.imread(slider_path, 0)
    
    # 模板匹配:查找滑块在背景图中的位置
    result = cv2.matchTemplate(bg, slider, cv2.TM_CCOEFF_NORMED)
    # 获取匹配结果的最大值坐标
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    
    # 缺口横坐标(根据实际图片尺寸微调)
    gap_x = max_loc[0]
    print(f"识别到缺口横坐标:{gap_x}")
    return gap_x

# 获取缺口位置
gap_x = get_gap_position(bg_path, slider_path)

步骤 4:模拟拟人滑动轨迹

机器匀速滑动会被直接拦截,我们需要生成先加速后减速、带微小抖动的拟人轨迹,模拟人类拖动行为。

python

运行

plain 复制代码
def get_slide_track(distance):
    """生成拟人滑动轨迹:返回每一步的偏移量"""
    track = []
    current = 0
    # 加速度与减速阈值
    mid = distance * 4 / 5
    t = 0.2
    v = 0
    
    while current < distance:
        if current < mid:
            a = 2  # 加速阶段
        else:
            a = -3  # 减速阶段
        v0 = v
        v = v0 + a * t
        move = v0 * t + 0.5 * a * t * t
        current += move
        # 添加微小抖动,更拟人
        track.append(round(move + random.uniform(-0.5, 0.5), 2))
    return track

def slide_captcha(driver, gap_x):
    """模拟滑动拼图验证"""
    # 定位滑块元素
    slider = driver.find_element(By.CLASS_NAME, "slider-btn")
    # 生成滑动轨迹
    track = get_slide_track(gap_x - 10)  # 微调偏移量
    
    # 按住滑块
    ActionChains(driver).click_and_hold(slider).perform()
    time.sleep(random.uniform(0.2, 0.5))
    
    # 按照轨迹滑动
    for step in track:
        ActionChains(driver).move_by_offset(xoffset=step, yoffset=0).perform()
        time.sleep(random.uniform(0.005, 0.01))
    
    # 随机停顿后释放
    time.sleep(random.uniform(0.3, 0.6))
    ActionChains(driver).release().perform()
    time.sleep(2)
    
    # 判断验证是否成功
    try:
        driver.find_element(By.CLASS_NAME, "captcha-success")
        print("滑动验证成功!")
        return True
    except:
        print("滑动验证失败,重试中...")
        return False

# 执行滑动验证,最多重试3次
retry_count = 0
while retry_count < 3:
    if slide_captcha(driver, gap_x):
        break
    retry_count += 1
    time.sleep(1)

步骤 5:验证通过后批量爬取网页图片

滑动验证成功后,反爬限制解除,我们可以直接定位网页中的图片元素,批量下载并保存。

python

运行

plain 复制代码
def download_img(img_url, save_path):
    """下载单张图片"""
    try:
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
        }
        response = requests.get(img_url, headers=headers, timeout=10)
        with open(save_path, "wb") as f:
            f.write(response.content)
        return True
    except Exception as e:
        print(f"图片下载失败:{e}")
        return False

def crawl_target_imgs(driver):
    """批量爬取网页图片"""
    # 定位所有图片元素(根据实际网页修改选择器)
    img_elements = driver.find_elements(By.XPATH, '//div[@class="img-list"]//img')
    print(f"共找到{len(img_elements)}张图片")
    
    success_count = 0
    for index, img in enumerate(img_elements):
        # 获取图片真实地址
        img_url = img.get_attribute("src")
        if not img_url or img_url.startswith("data:image"):
            continue
        save_path = f"target_imgs/img_{index+1}.jpg"
        # 下载图片
        if download_img(img_url, save_path):
            success_count += 1
            print(f"第{success_count}张图片下载完成")
        time.sleep(random.uniform(0.5, 1))  # 随机延时,避免请求过快
    
    print(f"图片爬取完成,成功下载{success_count}/{len(img_elements)}张")

# 执行图片爬取
crawl_target_imgs(driver)

# 关闭浏览器
driver.quit()

五、代码优化与反爬规避进阶技巧

以上代码可实现基础的滑动拼图破解与图片爬取,在实际生产环境中,我们可以通过以下方式提升稳定性:

  1. 动态 UA 切换:每次请求更换 User-Agent,避免 UA 被拉黑;
  2. 代理 IP 池:使用高匿代理 IP,解决 IP 封禁问题(推荐使用亿牛云爬虫代理);
  3. 轨迹优化:增加随机停顿、轻微上下偏移,更贴合人类滑动习惯;
  4. 图片预加载:提前缓存验证码图片,提升识别速度;
  5. 异常重试机制:针对验证失败、图片加载失败等场景,增加自动重试逻辑。

六、总结

滑动拼图反爬是前端人机验证的基础形态,其核心难点在于缺口精准识别拟人轨迹模拟。本文通过 Python+OpenCV+Selenium 的技术组合,实现了从验证破解到图片爬取的全流程自动化:OpenCV 解决了机器视觉识别问题,拟人滑动轨迹绕过了前端行为检测,最终实现高效、稳定的网页图片爬取。

对于爬虫开发者而言,掌握滑动拼图破解只是起点,后续可延伸学习极验验证码、文字点选、无感验证等更复杂的反爬机制。在技术实践中,始终坚守合规底线,才能让爬虫技术真正发挥数据采集与分析的价值。

相关推荐
用户83562907805113 小时前
Python 操作 PDF 附件:添加、查看与管理指南
后端·python
宇宙之一粟21 小时前
乐企版式文件生成平台
java·后端·python
学测绘的小杨2 天前
CompassFusion:一个从 GNSS 到 GNSS/INS 组合导航的独立工程包
python
zzzzzz3102 天前
当产品经理说这个很简单:我用Python自动化处理奇葩需求的实战指南
python·pycharm·产品经理
雪隐2 天前
个人电脑玩AI-06让5060 Ti给你打工——不光能画画,Qwen3-TTS还能学人说话,连我老板都信了!
人工智能·后端·python
兵慌码乱2 天前
面向桌面端的资产管理系统分层架构设计与核心模块实现
python·系统架构·sqlite·pyqt5·数据库设计·桌面应用开发·mvc架构
hboot2 天前
AI工程师第三课 - 机器学习基础
python·scikit-learn·kaggle
顾林海3 天前
Agent入门阶段-编程基础-Python:流程控制
python·agent·ai编程
呱呱复呱呱3 天前
Django CBV 源码解读:一个请求是怎么找到你的 get() 方法的
python·django
Caco_D3 天前
一行代码抓遍全网 20 个热榜!Aneiang.Pa 4.0 发布 — 极简 .NET 爬虫库
爬虫·.net