本文共 5981 字,大约阅读时间需要 19 分钟。
环境安装
安装python需要的依赖包 cv2 安装可以参考这里: 安装webdriver -> chrome 下载对应版本,放在本地 D:\anaconda3\Scripts 目录下效果展示
GIF效果: cv2使用参考: 注意:测试时慢点刷,容易封IP。源码
有问题可以留言探讨,公众号:JavaPub 对源码加了大量注释 测试网站:import osimport cv2import timeimport randomimport requestsimport numpy as npfrom PIL import Imagefrom io import BytesIOfrom selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver import ActionChainsfrom selenium.webdriver.support.wait import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECclass CrackSlider(): def __init__(self): self.browser = webdriver.Chrome() self.s2 = r'//*[@id="captcha_div"]/div/div[1]/div/div[1]/img[1]' self.s3 = r'//*[@id="captcha_div"]/div/div[1]/div/div[1]/img[2]' self.url = 'http://app.miit-eidc.org.cn/miitxxgk/gonggao/xxgk/queryCpParamPage?dataTag=Z&gid=U3119671&pc=303' self.wait = WebDriverWait(self.browser, 20) self.browser.get(self.url) def get_img(self, target, template, xp): time.sleep(3) target_link = self.browser.find_element_by_xpath(self.s2).get_attribute("src") template_link = self.browser.find_element_by_xpath(self.s3).get_attribute("src") target_img = Image.open(BytesIO(requests.get(target_link).content)) template_img = Image.open(BytesIO(requests.get(template_link).content)) target_img.save(target) template_img.save(template) size_loc = target_img.size print('size_loc[0]-----\n') print(size_loc[0]) zoom = xp / int(size_loc[0]) print('zoom-----\n') print(zoom) return zoom def change_size(self, file): image = cv2.imread(file, 1) img = cv2.medianBlur(image, 5) b = cv2.threshold(img, 15, 255, cv2.THRESH_BINARY) binary_image = b[1] binary_image = cv2.cvtColor(binary_image, cv2.COLOR_BGR2GRAY) x, y = binary_image.shape edges_x = [] edges_y = [] for i in range(x): for j in range(y): if binary_image[i][j] == 255: edges_x.append(i) edges_y.append(j) left = min(edges_x) right = max(edges_x) width = right - left bottom = min(edges_y) top = max(edges_y) height = top - bottom pre1_picture = image[left:left + width, bottom:bottom + height] return pre1_picture def match(self, target, template): img_gray = cv2.imread(target, 0) img_rgb = self.change_size(template) template = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) run = 1 L = 0 R = 1 while run < 20: run += 1 threshold = (R + L) / 2 if threshold < 0: print('Error') return None loc = np.where(res >= threshold) if len(loc[1]) > 1: L += (R - L) / 2 elif len(loc[1]) == 1: break elif len(loc[1]) < 1: R -= (R - L) / 2 res = loc[1][0] print('match distance-----\n') print(res) return res def move_to_gap(self, tracks): slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'yidun_slider'))) ActionChains(self.browser).click_and_hold(slider).perform() while tracks: x = tracks.pop(0) ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform() time.sleep(0.05) ActionChains(self.browser).release().perform() def move_to_gap1(self, distance): distance += 46 time.sleep(1) element = self.browser.find_element_by_xpath(self.s3) ActionChains(self.browser).click_and_hold(on_element=element).perform() ActionChains(self.browser).move_to_element_with_offset(to_element=element, xoffset=distance, yoffset=0).perform() time.sleep(1.38) ActionChains(self.browser).release(on_element=element).perform() def move_to_gap2(self, distance): element = self.browser.find_elements_by_class_name("yidun_slider")[0] action = ActionChains(self.browser) mouse_action = action.click_and_hold(on_element=element) distance += 11 distance = int(distance * 32/33) move_steps = int(distance/4) for i in range(0,move_steps): mouse_action.move_by_offset(4,random.randint(-5,5)).perform() time.sleep(0.1) mouse_action.release().perform() def get_tracks(self, distance, seconds, ease_func): distance += 20 tracks = [0] offsets = [0] for t in np.arange(0.0, seconds, 0.1): ease = ease_func offset = round(ease(t / seconds) * distance) tracks.append(offset - offsets[-1]) offsets.append(offset) tracks.extend([-3, -2, -3, -2, -2, -2, -2, -1, -0, -1, -1, -1]) return tracks def get_tracks1(self, distance): """根据偏移量获取移动轨迹 :param distance: 偏移量 :return: 移动轨迹 """ track = [] current = 0 mid = distance * 4 / 5 t = 0.2 v = 0 while current < distance: if current < mid: a = 4 else: a = -3 v0 = v v = v0 + a * t move = v0 * t + 1 / 2 * a * t * t current += move track.append(round(move)) return track def ease_out_quart(self, x): res = 1 - pow(1 - x, 4) return resif __name__ == '__main__': xp = 320 target = 'target.jpg' template = 'template.png' cs = CrackSlider() zoom = cs.get_img(target, template, xp) distance = cs.match(target, template) track = cs.get_tracks((distance + 7) * zoom, random.randint(2, 4), cs.ease_out_quart) cs.move_to_gap(track)
转载地址:http://qyfwk.baihongyu.com/