吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 600|回复: 7
收起左侧

[Web逆向] An某客点选加滑块验证Selenium版本

[复制链接]
HGG001 发表于 2025-3-18 15:12
新手入门,水平一般,巨佬们多多指教!

地址:aHR0cHM6Ly93d3cuYW5qdWtlLmNvbS9jYXB0Y2hhLXZlcmlmeS8=



直接上源码,注释清晰,可放心食用!

[Python] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
import os
import cv2
import time
import random
import requests
import numpy as np
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
 
ImgLocation = 'img_location'  # 图片存放的位置
 
 
def requests_ip():
    """
    请求代理
    :return:Ip:Port
    """[/align][align=left]
# 这里是获取代理IP的API
    res = requests.get('')[/align][align=left]
    print(res.text)
    return res.text
 
 
def save_yzm(driver):
    """保存验证码"""
    if not os.path.exists(ImgLocation):
        os.mkdir(ImgLocation)
    bg_img = driver.find_element(By.XPATH, '//*[@id="ISDCaptcha"]/div/div[1]/div[4]/div[1]/div[2]/div/div/div[1]/div[2]').get_attribute('style')
 
    puzzle_img = driver.find_element(By.XPATH, '//*[@id="ISDCaptcha"]/div/div[1]/div[4]/div[1]/div[2]/div/div/div[1]/div[1]/div[1]').get_attribute('style')
 
    img_url = bg_img.split('"')[1]
    puzzle_url = puzzle_img.split('"')[1]
 
    # print("验证码背景链接获取成功!", img_url)
    # print("验证码缺口链接获取成功!", puzzle_url)
    proxy = {
        "http": "",
        "https": ""
    }
    content = requests.get(img_url, proxies=proxy).content
    with open(f'./{ImgLocation}/bgImgUrl.png', 'wb') as f:
        f.write(content)
 
    content1 = requests.get(puzzle_url, proxies=proxy).content
    with open(f'./{ImgLocation}/puzzleImgUrl.png', 'wb') as f:
        f.write(content1)
 
 
def find_puzzle(bg_img_path=f'./{ImgLocation}/bgImgUrl.png', puzzle_img_path=f'./{ImgLocation}/puzzleImgUrl.png'):
    """
    计算缺口位置
    :param bg_img_path: 背景图片
    :param puzzle_img_path: 缺口图片
    :return: 需要移动的距离
    """
    img = cv2.imdecode(np.fromfile(bg_img_path, dtype=np.uint8), cv2.IMREAD_COLOR)
    tpl = cv2.imdecode(np.fromfile(puzzle_img_path, dtype=np.uint8), cv2.IMREAD_COLOR)
 
    img_gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, img_bw = cv2.threshold(img_gry, 127, 255, cv2.THRESH_BINARY)
 
    tpl = cv2.cvtColor(tpl, cv2.COLOR_BGR2GRAY)
    for row in range(tpl.shape[0]):
        for col in range(tpl.shape[1]):
            if tpl[row, col] == 0:
                tpl[row, col] = 96
    lower = np.array([96])
    upper = np.array([96])
    mask = cv2.inRange(tpl, lower, upper)
    tpl[mask == 0] = 0
    tpl[mask != 0] = 255
 
    result = cv2.matchTemplate(img_bw, tpl, cv2.TM_CCOEFF_NORMED)
    _, _, _, max_loc = cv2.minMaxLoc(result)
    # 0.8245这个比例是网页上的数据和实际图片大小的比例
    distance = int(max_loc[0] * 0.8245) + random.randint(1, 3)
    return distance
 
 
def generate_track(distance):
    """
    滑动轨迹拟合
    :param distance: 界面上的实际滑动的距离
    :return: x轴和y轴的轨迹
    """
    ratio = distance / 126
    # print(ratio)
    new_track = []
    base_track = ['29,11,0', '29,11,11', '29,11,26', '33,11,56', '34,11,66', '36,11,67', '39,11,76', '41,11,83',
                  '43,11,86', '46,11,92', '49,11,98', '50,11,102', '52,11,106', '53,11,111', '55,11,116',
                  '57,11,118', '59,11,123', '60,11,126', '62,11,132', '64,12,134', '65,12,138', '66,12,142',
                  '68,12,148', '69,12,151', '70,13,155', '71,13,158', '72,13,164', '74,13,166', '75,13,170',
                  '76,14,174', '77,14,180', '79,14,182', '81,14,186', '82,14,196', '84,14,198', '86,14,207',
                  '87,15,212', '89,15,219', '90,15,223', '92,15,230', '93,15,234', '94,15,239', '95,15,243',
                  '98,15,246', '100,15,250', '102,15,260', '105,15,262', '106,15,266', '108,15,270', '109,16,276',
                  '111,16,278', '113,16,283', '115,16,286', '117,16,291', '118,16,294', '119,16,298', '121,16,302',
                  '123,16,309', '124,16,311', '125,16,315', '126,16,319', '129,16,324', '130,16,327', '131,16,331',
                  '132,16,334', '132,16,388', '132,16,522', '133,16,566', '134,16,574', '135,16,575', '136,16,594',
                  '137,16,620', '138,16,625', '139,16,652', '140,16,657', '141,17,676', '141,18,680', '142,18,684',
                  '143,18,688', '144,18,716', '145,18,724', '146,18,796', '147,19,828', '148,19,860', '149,19,888',
                  '149,19,890', '150,19,916', '151,20,932', '152,20,936', '152,20,1021', '153,20,1150', '154,20,1152',
                  '155,20,1236', '155,20,1388', '155,20,1522', '155,20,1717']
    for track in base_track:
        t = track.split(",")
        new_track.append((str(int(int(t[0]) * ratio)), str(t[1]), str(int(int(t[2]) * ratio))))
    # print("轨迹:", new_track)
    # 返回结果为元组
    tracks = [(int(x), int(y), int(z)) for x, y, z in new_track]
    # 从元组中分离x轴和y轴
    anjuke_x = [x[0] for x in tracks]
    anjuke_y = [x[1] for x in tracks]
    # 计算x轴轨迹偏移量
    x_list = [0] + [anjuke_x[i] - anjuke_x[i - 1] for i in range(1, len(anjuke_x))]
    # 计算y轴轨迹偏移量
    y_list = [0] + [anjuke_y[i] - anjuke_y[i - 1] for i in range(1, len(anjuke_y))]
 
    return x_list, y_list
 
 
def drag_slider(url):
    # 创建Chromium Options对象
    options = webdriver.ChromeOptions()
    # 添加Chromium浏览器的可执行文件路径
    options.binary_location = ''
    # 用户数据目录
    options.add_argument("")
    # 创建Chromium WebDriver实例
    driver = webdriver.Chrome(service=Service(''),
                              options=options)
    driver.maximize_window()  # 窗口最大化
    # 设置超时停止加载
    driver.set_page_load_timeout(10)
 
    driver.get(url)
    # 等到元素出现在进行操作
    wait = WebDriverWait(driver, 10)
    wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="ISDCaptcha"]/div/div[1]/div[1]')))
 
    # 定位点击验证按钮
    button = driver.find_element(By.XPATH, '//*[@id="ISDCaptcha"]/div/div[1]/div[1]')
    button.click()
    time.sleep(2)
    wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="ISDCaptcha"]/div/div[1]/div[4]/div[1]/div[2]/div/div/div[2]/div/div[3]')))
    # 定位滑块元素
    slider = driver.find_element(By.XPATH, '//*[@id="ISDCaptcha"]/div/div[1]/div[4]/div[1]/div[2]/div/div/div[2]/div/div[3]')
    action = ActionChains(driver, 10)
 
    # # 模拟摁住鼠标
    action.click_and_hold(slider).perform()
    time.sleep(1)
    save_yzm(driver)  # 保存验证码
    distance = find_puzzle()  # 计算缺口位置
    x_list, y_list = generate_track(distance)  # 计算滑块轨迹
    for i, _ in enumerate(x_list):
        action.move_by_offset(x_list[i], y_list[i]).perform()
    time.sleep(0.5)
    action.release().perform()
    time.sleep(10)
    new_url = driver.current_url
    print("验证url—直接:", url)
    print("跳转url—直接:", new_url)
 
    if new_url != url:
        return True
    else:
        pass
        # driver.refresh()
        time.sleep(2)
        diaoyong(url, driver)
    # 关闭浏览器
    driver.quit()
 
 
def diaoyong(code_url, driver):
    # 等到元素出现在进行操作
    wait = WebDriverWait(driver, 10)
    wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="ISDCaptcha"]/div/div[1]/div[4]/div[1]/div[2]/div/div/div[2]/div/div[3]')))
    # 定位滑块元素
    slider = driver.find_element(By.XPATH, '//*[@id="ISDCaptcha"]/div/div[1]/div[4]/div[1]/div[2]/div/div/div[2]/div/div[3]')
    action = ActionChains(driver, 10)
    # 模拟摁住鼠标
    action.click_and_hold(slider).perform()
    time.sleep(0.5)
    save_yzm(driver)  # 保存验证码
    distance = find_puzzle()  # 计算缺口位置
    x_list, y_list = generate_track(distance)  # 计算滑块轨迹
    for i, _ in enumerate(x_list):
        action.move_by_offset(x_list[i], y_list[i]).perform()
    time.sleep(0.5)
    action.release().perform()
    time.sleep(5)
    # 验证完成后跳转的url
    new_url = driver.current_url
    print("验证url—调用:", code_url)
    print("跳转url—调用:", new_url)
 
    if new_url != code_url:
        return True
    else:
        time.sleep(2)
        diaoyong(code_url, driver)
 
 
if __name__ == '__main__':
    url = ""
    drag_slider(url)

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
涛之雨 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

yitoumao 发表于 2025-3-18 18:14
易盾的App的能用吗?
wzh103103 发表于 2025-3-19 08:57
Onedaya 发表于 2025-3-19 09:36
wu1030 发表于 2025-3-19 09:50
收藏了,学习学习
黑猫的猫 发表于 2025-3-19 10:03
牛的,学习一下
ZhouEr 发表于 2025-3-19 10:07
牛啊大佬!
涛之雨 发表于 2025-3-21 12:25
可以补充一些逆向的过程,
一些关键数据是如何计算出来的,(就算是猜,也应该有个方向对吧)

在帮助他人的同时,也记录自己进步的点滴
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-1 08:41

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表