python入門教程 - 滑塊實戰[附源碼]

来源:https://www.cnblogs.com/JavaPub/archive/2022/03/25/16056986.html
-Advertisement-
Play Games

文末源碼,閱讀大約2.8分鐘 傻瓜式教程 - 體驗滑塊,提供練習場景及源碼。 @ 環境安裝 安裝python需要的依賴包 cv2 安裝可以參考這裡:https://javapub.blog.csdn.net/article/details/123656345 安裝webdriver → chrome ...


文末源碼,閱讀大約2.8分鐘

傻瓜式教程 - 體驗滑塊,提供練習場景及源碼。


@

目錄

image

環境安裝

安裝python需要的依賴包

cv2 安裝可以參考這裡:https://javapub.blog.csdn.net/article/details/123656345

安裝webdriver -> chrome

下載對應版本,放在本地 D:\anaconda3\Scripts 目錄下

https://registry.npmmirror.com/binary.html?path=chromedriver


效果展示

GIF效果:https://tva2.sinaimg.cn/large/007F3CC8ly1h0ku3yh9g5g31ex0pfwus.gif

動畫

cv2使用參考:https://blog.csdn.net/RNG_uzi_/article/details/90034485

註意:測試時慢點刷,容易封IP。

源碼

有問題可以留言探討,公眾號:JavaPub

對源碼加了大量註釋

測試網站:http://app.miit-eidc.org.cn/miitxxgk/gonggao/xxgk/queryCpParamPage?dataTag=Z&gid=U3119671&pc=303

import os
import cv2
import time
import random
import requests
import numpy as np
from PIL import Image
from io import BytesIO
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class CrackSlider():
    def __init__(self):
        # self.browser = webdriver.Edge()
        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)  # 讀取圖片 image_name應該是變數
        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) # 圖片格式轉換為灰度圖片 
        # cv2.imshow('template', template)
        # cv2.waitKey(0)
        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()
        #element = self.browser.find_element_by_xpath(self.s3)
        #ActionChains(self.browser).click_and_hold(on_element=element).perform()
        while tracks:
            x = tracks.pop(0)
            print('tracks.pop(0)-----\n')
            print(x)
            ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform()
            #ActionChains(self.browser).move_to_element_with_offset(to_element=element, xoffset=x, yoffset=0).perform()
            #time.sleep(0.01)
        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()
        #ActionChains(self.browser).release().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
            print('ease-----\n')
            print(ease)
            offset = round(ease(t / seconds) * distance)
            print('offset-----\n')
            print(offset)
            tracks.append(offset - offsets[-1])
            print('offset - offsets[-1]-----\n')
            print(offset - offsets[-1])
            offsets.append(offset)
            print('offsets-----\n')
            print(offsets)
        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:
                # 加速度為正 2
                a = 4
            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))
        return track

    def ease_out_quart(self, x):
        res = 1 - pow(1 - x, 4)
        print('ease_out_quart-----\n')
        print(res)
        return res

# 發生意外,請留言。https://javapub.blog.csdn.net/article/details/123730597
if __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)
    #track = cs.get_tracks1(distance)
    #track = cs.get_tracks((distance + 7) * zoom, random.randint(1, 2), cs.ease_out_quart)
    cs.move_to_gap(track)
    #cs.move_to_gap1(distance)
    #cs.move_to_gap2(distance)
    time.sleep(2)
    #cs.browser.close()

同名公眾號,更多工具解決方案

image


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 近期熱播的電視劇《人世間》,講述了70年代無數普通人的故事,細膩的人物形象和真實的故事感動著我們。原來在那個年代,我們的父母和祖輩都在為新中國的美好生活而奮鬥著,為國家捨棄了小家團聚的機會;原來在那個年代,擁有一張合照也不是容易的事情。 多年來,隨著影像技術的迭代更新,人們的多彩生活被即時記錄著。同 ...
  • 前言 ​ 埋點一般可以分為客戶端埋點和後端埋點。由於客戶端埋點更加貼近業務,更加直觀,因此稱為市面上主流數據採集手段。對於 iOS 端的埋點,目前市面上主流代碼埋點和全埋點兩種方案。其中,代碼埋點即顯式地調用數據採集 SDK 提供的介面來採集數據,在採集能力上有比較大的優勢,但是需要做額外的開發,易 ...
  • Javascript中的for是如何實現迴圈的? 一、語法結構 單for迴圈 for (初始化變數; 條件表達式; 操作表達式) { 迴圈體 } 雙重for迴圈(也叫迴圈嵌套) for (外層初始化變數; 外層的表達式; 外層的操作表達式) { for (裡層的初始化變數; 裡層的條件表達式; 裡層 ...
  • 限時限次數點擊按鈕 思路: 用一個變數作為計數,點擊一次,計數加一 點擊函數內判斷計數變數 設置定時恢復 實現 HTML代碼 <body> <div class="a123"> <a class="btn bg1" onclick="doIt()">123123</a> <br> <div clas ...
  • 一、什麼講單例模式 單例模式,最簡單的理解是對象實例只有孤單的一份,不會重覆創建實例。 這個模式已經很經典了,經典得我不再贅述理論,只給簡單註釋,畢竟教科書詳盡太多。 解決 sonar RSPEC-2168 異味的時候,發現目前業界推薦的單例模式和教科書上的已經有了較大差異,雙重鎖定不再推薦,甚至業 ...
  • Keep It Simple, Stupid. 這是開發人耳熟能詳的 KISS 原則,也像是一句有調侃意味的善意提醒,提醒每個前端人,簡潔易懂的用戶體驗和刪繁就簡的搭建邏輯就是前端開發的至簡大道。 這也是袋鼠雲數棧前端開發團隊追求的目標。 數棧是一個專註一站式產品體系,覆蓋數據全鏈路開發流程,全面國 ...
  • 一,server 端的存儲模式為:Server 端 存 儲 模 式 (store-mode) 支 持 三 種 : file: ( 默 認 ) 單 機 模 式 , 全 局 事 務 會 話 信 息 內 存 中 讀 寫 並 持 久 化 本 地 文 件 root.data , 性 能 較 高 ( 默 認 ) ...
  • 一:遍歷 A:遍歷 方式1: public static void printArray(int[] arr) { for(int x=0; x<arr.length; x++) { System.out.println(arr[x]); } } 方式2: public static void pr ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...