需要安装库 cv2
pip install opencv python
实现过程:
1.下载滑块验证,运行该文件调用main.py
check_slide.py
# -*- coding: utf-8 -*-
from selenium import webdriver
import requests
from main import SlideCrack
from lxml import etree
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
def get_track(distance):
"""
根据偏移量获取移动轨迹
:param distance: 偏移量
:return: 移动轨迹
"""
# 移动轨迹
track = []
# 当前位移
current = 0
# 减速阈值
mid = distance * 4 / 5
# 计算间隔
t = 0.2
# 初速度
v = 0
while current < distance:
if current < mid:
# 加速度为正 2
a = 4.5
else:
# 加速度为负 3
a = -3
# 初速度 v0
v0 = v
# 当前速度 v = v0 + at
v = v0 + a * t
# 移动距离 x = v0t + 1/2 * a * t^2
move = v0 * t + 1 / 2 * a * t * t
# 当前位移
current += move
# 加入轨迹
track.append(round(move))
# print '轨迹 ', track
return track
# 下载图片,返回图片名
def download_img(url, name):
print('下载图片:', name)
res = requests.get(url)
with open(name + '.jpg', 'wb') as f:
f.write(res.content)
return name + '.jpg'
def get_page_sourse(user, password):
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
# 添加实验性质的设置参数
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options)
driver.execute_cdp_cmd(
"Page.addScriptToEvaluateOnNewDocument",
{
"source":
"""
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
}
)
# 以下部分是获取验证码图片页
driver.get("https://live.kuaishou.com/v/hot/")
time.sleep(1)
# 网页最大化
driver.maximize_window()
# 点击登录
driver.find_element_by_class_name('login').click()
print('点击', driver.find_element_by_class_name('login').text)
time.sleep(0.5)
# 选择账号密码登录
driver.find_elements_by_class_name('login-tab-title')[1].click()
time.sleep(0.5)
driver.find_element_by_class_name('change-login').click()
time.sleep(0.5)
# 输入账号密码
input_name = driver.find_elements_by_class_name('pl-input-text')[1]
input_pwd = driver.find_elements_by_class_name('pl-input-text')[2]
time.sleep(1)
input_name.send_keys(user)
time.sleep(0.5)
input_pwd.send_keys(password)
# 点击登录按钮
driver.find_element_by_class_name('login-button').click()
time.sleep(1)
# 找到子窗口
iframe = driver.find_element_by_xpath('//*[@id="captcha-container"]/iframe')
# 切换到子窗口
driver.switch_to.frame(iframe)
# 背景图
check_img_ele = driver.find_element_by_xpath('//div[@class="image-container"]/img[@class="bg-img"]')
check_img = check_img_ele.get_attribute('src')
bg = download_img(check_img, 'check_img')
# 滑块图
slider_img_ele = driver.find_element_by_xpath('//div[@class="image-container"]/img[@class="slider-img"]')
slider_img = slider_img_ele.get_attribute('src')
gap = download_img(slider_img, 'slider_img')
# 需要新建一张空白初始化图片
out = 'out.jpg'
discern = SlideCrack(bg, gap, out)
long = discern.discern()
long_list = get_track(long)
# 定位拖动滚动条按钮
hover = driver.find_element_by_xpath('//div[@class="slider"]//div[@class="slider-btn"]')
# 拖动条按钮
action = webdriver.ActionChains(driver)
action.click_and_hold(hover).perform()
for i in long_list:
action.move_by_offset(i, 0).perform()
action = webdriver.ActionChains(driver)
action.release().perform()
time.sleep(5)
cookie_items = driver.get_cookies()
cookie_str = ""
for item_cookie in cookie_items:
item_str = item_cookie["name"] + "=" + item_cookie["value"] + "; "
cookie_str += item_str
print('Success get cookie:' + cookie_str)
return cookie_str
cookie_str = get_page_sourse('', '')
print(cookie_str)
2.图片处理部分
main.py
# -*- coding: utf-8 -*-
import cv2
class SlideCrack(object):
def __init__(self, gap, bg, out):
"""
init code
:param gap: 缺口图片
:param bg: 背景图片
:param out: 输出图片
"""
self.gap = gap
self.bg = bg
self.out = out
@staticmethod
def clear_white(img):
# 清除图片的空白区域,这里主要清除滑块的空白
img = cv2.imread(img)
rows, cols, channel = img.shape
min_x = 255
min_y = 255
max_x = 0
max_y = 0
for x in range(1, rows):
for y in range(1, cols):
t = set(img[x, y])
if len(t) >= 2:
if x <= min_x:
min_x = x
elif x >= max_x:
max_x = x
if y <= min_y:
min_y = y
elif y >= max_y:
max_y = y
img1 = img[min_x:max_x, min_y: max_y]
return img1
def template_match(self, tpl, target):
th, tw = tpl.shape[:2]
result = cv2.matchTemplate(target, tpl, cv2.TM_CCOEFF_NORMED)
# 寻找矩阵(一维数组当作向量,用Mat定义) 中最小值和最大值的位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
tl = max_loc
br = (tl[0] + tw, tl[1] + th)
# 绘制矩形边框,将匹配区域标注出来
# target:目标图像
# tl:矩形定点
# br:矩形的宽高
# (0,0,255):矩形边框颜色
# 1:矩形边框大小
cv2.rectangle(target, tl, br, (0, 0, 255), 2)
cv2.imwrite(self.out, target)
return tl[0]
@staticmethod
def image_edge_detection(img):
edges = cv2.Canny(img, 100, 200)
return edges
def discern(self):
img1 = self.clear_white(self.gap)
img1 = cv2.cvtColor(img1, cv2.COLOR_RGB2GRAY)
slide = self.image_edge_detection(img1)
back = cv2.imread(self.bg, 0)
back = self.image_edge_detection(back)
slide_pic = cv2.cvtColor(slide, cv2.COLOR_GRAY2RGB)
back_pic = cv2.cvtColor(back, cv2.COLOR_GRAY2RGB)
x = self.template_match(slide_pic, back_pic)
# 输出横坐标, 即 滑块在图片上的位置
# print(x)
x = 1.23*x
return x
if __name__ == "__main__":
# 滑块图片
image1 = "img/4.png"
# 背景图片
image2 = "img/4_1.png"
# 处理结果图片,用红线标注
image3 = "img/4_2.png"
sc = SlideCrack(image1, image2, image3)
sc.discern()