image_diff.py图片处理文件
from skimage.measure import compare_ssim
import argparse
import imutils
import cv2
import numpy as np
from base64 import b64decode
class Diff:
def __init__(self, b1, b2, b3):
self.imageA = cv2.imdecode(np.frombuffer(b64decode(b1), np.uint8), cv2.COLOR_RGB2BGR)
self.imageB = cv2.imdecode(np.frombuffer(b64decode(b2), np.uint8), cv2.COLOR_RGB2BGR)
self.imageC = cv2.imdecode(np.frombuffer(b64decode(b3), np.uint8), cv2.COLOR_RGB2BGR)
def show(self):
cv2.imshow('imga', self.imageA)
cv2.imshow('imgb', self.imageB)
cv2.imshow('imgc', self.imageC)
if chr(cv2.waitKey(0)) == 'q':
cv2.destroyAllWindows()
def hOption(self):
grayA = cv2.cvtColor(self.imageA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(self.imageB, cv2.COLOR_BGR2GRAY)
grayC = cv2.cvtColor(self.imageC, cv2.COLOR_BGR2GRAY)
npArr_3 = np.array(grayC)
return self.diff(grayA, grayB, npArr_3)
def diff(self, grayA, grayB, npArr_3):
(score, diff) = compare_ssim(grayA, grayB, full=True)
diff = (diff * 255).astype("uint8")
print('图片相似度为:%s' % score)
return self.tf(diff, npArr_3)
def tf(self, diff, npArr_3):
thresh = cv2.threshold(diff, 0, 255,
cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[1] if imutils.is_cv3() else cnts[0]
img3_t = cv2.threshold(npArr_3, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cnts_3 = cv2.findContours(img3_t.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts_3 = cnts_3[1] if imutils.is_cv3() else cnts_3[0]
return self.getBr(cnts, cnts_3)
def getBr(self, cnts, cnts_3):
x1, y1, w1, h1 = cv2.boundingRect(cnts[-1])
cv2.rectangle(self.imageA, (x1, y1), (x1 + w1, y1 + h1), (0, 0, 255), 1)
cv2.rectangle(self.imageB, (x1, y1), (x1 + w1, y1 + h1), (0, 0, 255), 1)
x2, y2, w2, h2 = cv2.boundingRect(cnts_3[-1])
cv2.rectangle(self.imageC, (x2, y2), (x2 + w2, y2 + h2), (0, 0, 255), 1)
cv2.rectangle(self.imageC, (x2, y2), (x2 + w2, y2 + h2), (0, 0, 255), 1)
return x1 - x2
seleclass.py主入口文件
# -*- coding: utf-8 -*-
import json
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from image_diff import Diff
class SeleClass:
def __init__(self, url, username, password):
self.url = url
self.wdc_option = webdriver.ChromeOptions()
self.wdc_option.add_argument('--headless')
self.wdc_option.add_argument('--disable-gpu')
self.wdc = webdriver.Chrome(options=self.wdc_option)
self.wdc.implicitly_wait(10)
self.wdc.get(self.url)
self.wdc.maximize_window()
self.input(username, password)
def input(self, username, password):
self.wdc.find_element_by_id('login-username').send_keys(username)
self.wdc.find_element_by_id('login-passwd').send_keys(password)
self.mouseLogin()
def mouseLogin(self):
ActionChains(self.wdc).move_to_element(self.wdc.find_elements_by_class_name('btn-login')[0]).perform()
ActionChains(self.wdc).click().perform()
self.mouseMove(Diff(**self.getBase64Data()).hOption())
self.isLogin()
def doScript(self, script):
for _ in range(10):
try:
if len(self.wdc.execute_script(script)) < 3000:
print('错误数据大小:%s' % len(self.wdc.execute_script(script)), end='\\t')
raise BaseException()
return self.wdc.execute_script(script)
except:
time.sleep(1)
raise BaseException('拉取数据超时')
def mouseMove(self, long):
print('鼠标移动位移为:%s' % long)
ActionChains(self.wdc).click_and_hold(
self.wdc.find_elements_by_class_name('geetest_slider_button')[0]).perform()
ActionChains(self.wdc).move_by_offset(long, 0).perform()
time.sleep(1)
ActionChains(self.wdc).release().perform()
def getBase64Data(self):
bg = self.doScript("return $('.geetest_canvas_bg')[0].toDataURL('image/png')")[22::]
full = self.doScript("return $('.geetest_canvas_fullbg')[0].toDataURL('image/png')")[22::]
slice = self.doScript("return $('.geetest_canvas_slice')[0].toDataURL('image/png')")[22::]
print('真实数据大小:', len(bg), len(full), len(slice))
return {
'b1': bg,
'b2': full,
'b3': slice
}
def isLogin(self):
for _ in range(10):
if self.wdc.get_cookie('DedeUserID'):
self.wdc.get('<https://space.bilibili.com/>' + self.wdc.get_cookie('DedeUserID')['value'])
print('登陆成功:%s' % self.wdc.find_element_by_id('h-name').text)
return
else:
time.sleep(1)
raise BaseException('页面跳转超时')
def __del__(self):
time.sleep(2)
self.wdc.close()
if __name__ == '__main__':
s = SeleClass('<https://passport.bilibili.com/login>', 'username', 'password')