145 lines
4.2 KiB
Markdown
145 lines
4.2 KiB
Markdown
使用Python和Playwright破解滑动验证码
|
||
|
||
滑动验证码是一种常见的验证码形式,通过拖动滑块将缺失的拼图块对准原图中的空缺位置来验证用户操作。本文将介绍如何使用Python中的OpenCV进行模板匹配,并结合Playwright实现自动化破解滑动验证码的过程。
|
||
|
||
所需技术
|
||
OpenCV模板匹配:用于识别滑块在背景图中的正确位置。
|
||
Python:主要编程语言。
|
||
Playwright:用于浏览器自动化,模拟用户操作。
|
||
破解过程概述
|
||
获取验证码图像:
|
||
下载背景图和滑块图。
|
||
进行必要的图像预处理。
|
||
模板匹配:
|
||
使用OpenCV的模板匹配算法,计算滑块在背景图中的最佳匹配位置。
|
||
模拟滑动:
|
||
生成模拟人类滑动的轨迹,避免被识别为机器人。
|
||
使用Playwright模拟滑动操作。
|
||
实现步骤
|
||
|
||
设置环境
|
||
首先,我们需要设置Python环境并安装相关的依赖包。
|
||
sh
|
||
|
||
pip install playwright opencv-python-headless numpy
|
||
playwright install
|
||
|
||
2. 获取并预处理验证码图像
|
||
接下来,编写Python代码,下载验证码的背景图和滑块图,并对图像进行预处理。
|
||
|
||
python
|
||
|
||
import cv2
|
||
import numpy as np
|
||
import requests
|
||
from PIL import Image
|
||
from io import BytesIO
|
||
|
||
def get_images(bg_url, slider_url):
|
||
bg_response = requests.get(bg_url)
|
||
slider_response = requests.get(slider_url)
|
||
|
||
bg_image = Image.open(BytesIO(bg_response.content))
|
||
slider_image = Image.open(BytesIO(slider_response.content))
|
||
|
||
bg_image.save("background.png")
|
||
slider_image.save("slider.png")
|
||
|
||
def preprocess_images():
|
||
bg_img = cv2.imread('background.png')
|
||
slider_img = cv2.imread('slider.png', cv2.IMREAD_GRAYSCALE)
|
||
|
||
return bg_img, slider_img
|
||
在上述代码中,我们下载并保存验证码图像,然后将滑块图转换为灰度图进行处理。
|
||
|
||
模板匹配
|
||
使用OpenCV的模板匹配算法来确定滑块在背景图中的正确位置。
|
||
python
|
||
|
||
def find_slider_position(bg_img, slider_img):
|
||
result = cv2.matchTemplate(bg_img, slider_img, cv2.TM_CCOEFF_NORMED)
|
||
_, _, _, max_loc = cv2.minMaxLoc(result)
|
||
top_left = max_loc
|
||
|
||
return top_left[0]
|
||
|
||
bg_url = 'background_image_url'
|
||
slider_url = 'slider_image_url'
|
||
|
||
get_images(bg_url, slider_url)
|
||
bg_img, slider_img = preprocess_images()
|
||
slider_position = find_slider_position(bg_img, slider_img)
|
||
|
||
print('Slider Position:', slider_position)
|
||
这里我们使用TM_CCOEFF_NORMED算法进行匹配,并找到最佳匹配位置的坐标。
|
||
|
||
模拟滑动操作
|
||
通过生成一条模拟人类滑动的轨迹,并使用Playwright模拟滑动操作。
|
||
python
|
||
更多内容联系1436423940
|
||
from playwright.sync_api import sync_playwright
|
||
import time
|
||
import random
|
||
|
||
def generate_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))
|
||
|
||
return track
|
||
|
||
def simulate_slider_move(page, slider, track):
|
||
page.mouse.move(slider['x'], slider['y'])
|
||
page.mouse.down()
|
||
for x in track:
|
||
page.mouse.move(slider['x'] + x, slider['y'], steps=10)
|
||
time.sleep(random.uniform(0.02, 0.03))
|
||
page.mouse.up()
|
||
|
||
with sync_playwright() as p:
|
||
browser = p.chromium.launch(headless=False)
|
||
page = browser.new_page()
|
||
page.goto('your_target_website_with_captcha')更多内容访问ttocr.com或联系1436423940
|
||
|
||
slider = page.query_selector('your_slider_css_selector')
|
||
bounding_box = slider.bounding_box()
|
||
|
||
track = generate_track(slider_position)
|
||
simulate_slider_move(page, bounding_box, track)
|
||
|
||
browser.close()
|
||
|
||
## TypeScript 实现
|
||
|
||
项目中提供了等价的 TypeScript/Playwright 脚本 `src/slider.ts`,按照以下方式运行:
|
||
|
||
```bash
|
||
npm run slider -- <url> <滑块选择器> <拖动距离>
|
||
```
|
||
|
||
示例:
|
||
|
||
```bash
|
||
npm run slider -- https://example.com '.slider-handle' 180
|
||
```
|
||
|
||
脚本核心逻辑:
|
||
|
||
- `generateTrack(distance)`:生成类似人类滑动加速/减速的位移序列;
|
||
- `performSlide(page, selector, distance)`:定位滑块元素,模拟按下、移动及释放;
|
||
- 默认以非无头模式启动浏览器(可直接观察效果),完成滑动后自动关闭。
|
||
|