基于文本检测的 Python 爬虫弹窗图片定位与拖动实现

简介: 基于文本检测的 Python 爬虫弹窗图片定位与拖动实现

一、核心技术原理
(一)文本检测技术选型
弹窗图片中的文字是定位交互区域的关键标识,需通过光学字符识别(OCR)技术提取文本并确定位置。Tesseract-OCR 作为开源高效的 OCR 引擎,支持多语言识别且可通过训练优化精度,配合 Python 的 pytesseract 库可快速实现图片文本检测。同时,OpenCV 用于图片预处理(降噪、二值化),提升 OCR 识别准确率。
(二)弹窗定位逻辑
网页弹窗本质是 DOM 元素的动态渲染,通过 Selenium 模拟浏览器环境,可捕获弹窗对应的 HTML 节点。结合文本检测结果,将 OCR 识别到的目标文本(如 “拖动滑块”)与弹窗图片中的坐标关联,定位滑块起始位置与目标区域(通常为文本提示对应的缺口位置)。
(三)滑块拖动实现
滑块拖动需模拟人类操作轨迹,避免被反爬机制识别为机器行为。核心是生成非线性移动轨迹(加速 - 匀速 - 减速),通过 Selenium 的 ActionChains 类实现鼠标按下、移动、释放的连贯操作,同时控制移动时间与步长,模拟真实用户交互。
二、开发环境准备
(一)依赖库安装
需安装以下 Python 库,分别用于浏览器模拟、图片处理、OCR 识别及轨迹生成:

浏览器自动化库

pip install selenium

图片处理库

pip install opencv-python

OCR识别库

pip install pytesseract

图像处理辅助库

pip install pillow

数值计算库(用于轨迹生成)

pip install numpy
(二)环境配置

  1. Tesseract-OCR 安装:从官网下载安装包,配置系统环境变量(如 Windows 添加C:\Program Files\Tesseract-OCR),确保命令行输入tesseract --version可正常返回版本。
  2. 浏览器驱动配置:下载与本地 Chrome 版本匹配的 ChromeDriver,放置在 Python 脚本目录或系统环境变量路径中。
    三、完整实现流程
    (一)步骤拆解
  3. 网页访问与弹窗触发:通过 Selenium 打开目标网页,触发弹窗验证(如点击按钮、滚动页面)。
  4. 弹窗图片捕获:定位弹窗图片元素,截图并保存为本地文件。
  5. 图片预处理与文本检测:使用 OpenCV 优化图片质量,通过 Tesseract-OCR 提取文本及坐标。
  6. 目标区域定位:根据识别到的关键文本(如 “缺口”“验证”),确定滑块起始位置与目标位置。
  7. 模拟滑块拖动:生成人类行为轨迹,通过 ActionChains 执行拖动操作。
  8. 验证结果校验:判断验证是否成功,失败则重试。
    (二)核心代码实现
  9. 初始化浏览器与基础配置
    python
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.common.action_chains import ActionChains
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    import cv2
    import pytesseract
    from PIL import Image
    import numpy as np
    import time

配置Tesseract路径(Windows系统需指定)

pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

class SlideVerificationCrawler:
def init(self, url):

    # 初始化Chrome浏览器(无头模式可选)
    self.options = webdriver.ChromeOptions()
    self.options.add_experimental_option("excludeSwitches", ["enable-automation"])
    self.options.add_experimental_option('useAutomationExtension', False)
    self.driver = webdriver.Chrome(options=self.options)
    self.driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
        "source": """
        Object.defineProperty(navigator, 'webdriver', {
          get: () => undefined
        })
      """
    })
    self.url = url
    self.wait = WebDriverWait(self.driver, 10)

def open_page(self):
    """打开目标网页"""
    self.driver.get(self.url)
    self.driver.maximize_window()
    # 等待页面加载完成(根据实际网页调整等待条件)
    self.wait.until(EC.presence_of_element_located((By.TAG_NAME, 'body')))
    print("网页加载完成")
  1. 弹窗图片捕获与预处理
    python
    def capture_popup_image(self, popup_img_xpath):

     """捕获弹窗图片"""
     # 等待弹窗图片加载
     popup_img = self.wait.until(EC.presence_of_element_located((By.XPATH, popup_img_xpath)))
     # 获取图片位置与尺寸
     location = popup_img.location
     size = popup_img.size
     # 浏览器截图
     self.driver.save_screenshot('full_screen.png')
     # 裁剪弹窗图片
     full_img = Image.open('full_screen.png')
     left = location['x']
     top = location['y']
     right = left + size['width']
     bottom = top + size['height']
     popup_img_crop = full_img.crop((left, top, right, bottom))
     popup_img_path = 'popup_image.png'
     popup_img_crop.save(popup_img_path)
     print(f"弹窗图片已保存至{popup_img_path}")
     return popup_img_path
    

    def preprocess_image(self, img_path):

     """图片预处理:降噪、二值化提升OCR准确率"""
     img = cv2.imread(img_path)
     # 转为灰度图
     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
     # 高斯模糊降噪
     blur = cv2.GaussianBlur(gray, (3, 3), 0)
     # 自适应二值化
     thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
                                   cv2.THRESH_BINARY_INV, 11, 2)
     # 保存预处理后的图片
     preprocessed_img_path = 'preprocessed_image.png'
     cv2.imwrite(preprocessed_img_path, thresh)
     return preprocessed_img_path
    
  2. 文本检测与目标位置定位
    python
    def detect_text(self, img_path):

     """OCR文本检测:返回识别文本及对应坐标"""
     img = Image.open(img_path)
     # 配置Tesseract识别参数(中文识别+返回坐标)
     custom_config = r'--oem 3 --psm 6 -l chi_sim+eng makebox'
     # 执行OCR识别
     result = pytesseract.image_to_data(img, config=custom_config, output_type=pytesseract.Output.DICT)
     # 提取有效文本(过滤空字符串)
     text_info = []
     for i in range(len(result['text'])):
         text = result['text'][i].strip()
         if text:
             # 获取文本区域坐标(left, top, width, height)
             left = result['left'][i]
             top = result['top'][i]
             width = result['width'][i]
             height = result['height'][i]
             text_info.append({
                 'text': text,
                 'left': left,
                 'top': top,
                 'width': width,
                 'height': height,
                 'center_x': left + width // 2,
                 'center_y': top + height // 2
             })
     print(f"识别到的文本:{[info['text'] for info in text_info]}")
     return text_info
    

    def locate_target_area(self, text_info):

     """根据文本定位滑块起始位置与目标位置"""
     start_pos = None
     target_pos = None
     for info in text_info:
         # 假设“拖动滑块”对应滑块起始位置(可根据实际网页调整关键词)
         if '拖动滑块' in info['text']:
             start_pos = (info['center_x'], info['center_y'])
         # 假设“缺口”对应目标位置(可根据实际网页调整关键词)
         elif '缺口' in info['text']:
             target_pos = (info['center_x'], info['center_y'])
     if not start_pos or not target_pos:
         raise Exception("未识别到关键文本,无法定位目标区域")
     print(f"滑块起始位置:{start_pos},目标位置:{target_pos}")
     return start_pos, target_pos
    
  3. 滑块拖动轨迹生成与执行
    python
    def generate_track(self, distance):

     """生成模拟人类的滑块拖动轨迹(非线性)"""
     track = []
     current = 0
     # 加速阶段(前30%距离)
     accelerate_distance = distance * 0.3
     while current < accelerate_distance:
         # 加速度逐渐减小
         a = np.random.uniform(1.5, 2.5)
         v = current + a
         track.append(round(v))
         current += v
     # 匀速阶段(中间50%距离)
     uniform_distance = distance * 0.5
     while current < accelerate_distance + uniform_distance:
         v = np.random.uniform(2.0, 3.0)
         track.append(round(v))
         current += v
     # 减速阶段(最后20%距离)
     while current < distance:
         a = np.random.uniform(0.5, 1.0)
         v = max(0.5, current - (distance - current) * a)
         track.append(round(v))
         current += v
     # 确保总距离准确
     track = track[:-1] if sum(track) > distance else track
     track.append(distance - sum(track))
     return track
    

    def drag_slider(self, slider_xpath, start_pos, target_pos):

     """执行滑块拖动操作"""
     # 定位滑块元素
     slider = self.wait.until(EC.presence_of_element_located((By.XPATH, slider_xpath)))
     # 计算水平拖动距离(假设垂直方向无需移动)
     distance = target_pos[0] - start_pos[0]
     if distance <= 0:
         raise Exception("目标位置在起始位置左侧,距离计算错误")
     # 生成拖动轨迹
     track = self.generate_track(distance)
     print(f"拖动轨迹:{track},总距离:{sum(track)}")
     # 模拟鼠标操作
     action = ActionChains(self.driver)
     # 鼠标移动到滑块起始位置并按下
     action.move_to_element_with_offset(slider, start_pos[0], start_pos[1])
     action.click_and_hold().perform()
     time.sleep(0.2)  # 按下后停留0.2秒,模拟人类操作
     # 按轨迹移动鼠标
     for step in track:
         action.move_by_offset(step, np.random.randint(-2, 3))  # 垂直方向随机小幅度抖动
         action.perform()
         time.sleep(np.random.uniform(0.01, 0.03))  # 每步停留随机时间
     # 释放鼠标
     action.release().perform()
     time.sleep(1)  # 等待验证结果
    
  4. 主函数与验证流程
    python
    运行
    def run(self, popup_img_xpath, slider_xpath):
     """执行完整爬虫与验证流程"""
     try:
         # 1. 打开网页
         self.open_page()
         # 2. 触发弹窗(根据实际网页调整,如点击按钮)
         # 示例:self.driver.find_element(By.XPATH, '//button[@id="verify-btn"]').click()
         time.sleep(2)  # 假设弹窗自动弹出,等待2秒
         # 3. 捕获弹窗图片
         popup_img_path = self.capture_popup_image(popup_img_xpath)
         # 4. 图片预处理
         preprocessed_img_path = self.preprocess_image(popup_img_path)
         # 5. 文本检测
         text_info = self.detect_text(preprocessed_img_path)
         # 6. 定位目标区域
         start_pos, target_pos = self.locate_target_area(text_info)
         # 7. 拖动滑块
         self.drag_slider(slider_xpath, start_pos, target_pos)
         # 8. 验证结果校验(根据实际网页调整判断条件)
         if "验证成功" in self.driver.page_source:
             print("滑块验证成功!")
         else:
             print("验证失败,重试中...")
             self.run(popup_img_xpath, slider_xpath)  # 重试
     except Exception as e:
         print(f"执行失败:{str(e)}")
     finally:
         # 保持浏览器打开,便于调试(生产环境可注释)
         time.sleep(10)
         self.driver.quit()
    

示例:调用爬虫(需根据实际网页调整XPATH)

if name == "main":
target_url = "https://example.com/verify-page" # 目标网页URL

# 弹窗图片XPATH(需根据实际网页F12查看)
popup_img_xpath = '//div[@class="popup-img"]/img'
# 滑块元素XPATH(需根据实际网页F12查看)
slider_xpath = '//div[@class="slider-block"]'
crawler = SlideVerificationCrawler(target_url)
crawler.run(popup_img_xpath, slider_xpath)

四、关键优化与注意事项
(一)OCR 识别精度优化

  1. 针对弹窗图片特点,调整 OpenCV 预处理参数(如模糊核大小、二值化阈值),减少背景干扰。
  2. 若识别准确率低,可使用 Tesseract 训练工具(如 jTessBoxEditor)训练目标网页弹窗文字的专属字库。
  3. 结合关键词模糊匹配(如使用in关键字或正则表达式),提高关键文本识别容错率。
    (二)反爬机制规避
  4. 禁用 Selenium 的webdriver标识,通过 CDP 命令修改navigator.webdriver属性,避免被网页检测为爬虫。
  5. 拖动轨迹加入随机抖动(垂直方向 ±2 像素)和随机时间间隔(0.01-0.03 秒),模拟人类操作的不确定性。
  6. 避免操作速度过快,在鼠标按下、移动、释放等步骤中加入合理延时(如 0.2 秒按下停留)。
    (三)适应性调整
  7. 不同网页的弹窗文本、元素 XPATH 差异较大,需通过 F12 开发者工具查看实际 DOM 结构,调整关键词(如 “拖动滑块”“缺口”)和 XPATH 路径。
  8. 若弹窗图片为动态加载(如每次刷新不同),需在捕获图片前确保图片完全加载,可通过WebDriverWait等待图片naturalWidth属性大于 0。
相关文章
|
7天前
|
云安全 人工智能 自然语言处理
|
11天前
|
人工智能 Java API
Java 正式进入 Agentic AI 时代:Spring AI Alibaba 1.1 发布背后的技术演进
Spring AI Alibaba 1.1 正式发布,提供极简方式构建企业级AI智能体。基于ReactAgent核心,支持多智能体协作、上下文工程与生产级管控,助力开发者快速打造可靠、可扩展的智能应用。
990 35
|
5天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
670 4
|
7天前
|
机器学习/深度学习 人工智能 数据可视化
1秒生图!6B参数如何“以小博大”生成超真实图像?
Z-Image是6B参数开源图像生成模型,仅需16GB显存即可生成媲美百亿级模型的超真实图像,支持中英双语文本渲染与智能编辑,登顶Hugging Face趋势榜,首日下载破50万。
527 25
|
14天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
859 59
Meta SAM3开源:让图像分割,听懂你的话
|
4天前
|
弹性计算 网络协议 Linux
阿里云ECS云服务器详细新手购买流程步骤(图文详解)
新手怎么购买阿里云服务器ECS?今天出一期阿里云服务器ECS自定义购买流程:图文全解析,阿里云服务器ECS购买流程图解,自定义购买ECS的设置选项是最复杂的,以自定义购买云服务器ECS为例,包括付费类型、地域、网络及可用区、实例、镜像、系统盘、数据盘、公网IP、安全组及登录凭证详细设置教程:
195 114
|
11天前
|
人工智能 前端开发 算法
大厂CIO独家分享:AI如何重塑开发者未来十年
在 AI 时代,若你还在紧盯代码量、执着于全栈工程师的招聘,或者仅凭技术贡献率来评判价值,执着于业务提效的比例而忽略产研价值,你很可能已经被所谓的“常识”困住了脚步。
576 50
大厂CIO独家分享:AI如何重塑开发者未来十年
|
7天前
|
存储 自然语言处理 测试技术
一行代码,让 Elasticsearch 集群瞬间雪崩——5000W 数据压测下的性能避坑全攻略
本文深入剖析 Elasticsearch 中模糊查询的三大陷阱及性能优化方案。通过5000 万级数据量下做了高压测试,用真实数据复刻事故现场,助力开发者规避“查询雪崩”,为您的业务保驾护航。
382 25