滑動驗證最新版破解
- 1,打開浏覽器,并輸入查詢内容
- 2,執行js,生成帶缺口和不帶缺口的驗證碼圖檔
- 3,拿到滑動驗證碼需要移動的距離
- 4,生成滑動軌迹
- 5,拖動滑塊到缺口處
- 6,傳回html
-
- 結束語:
1,打開浏覽器,并輸入查詢内容
class CrackGeetest():
def __init__(self, url, proxy, word, searchId, bowtonID):
self.url = url
self.word = word # 搜尋關鍵詞
self.proxy = proxy # 加上代理IP
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--proxy-server=%s' % self.proxy)
# self.browser = webdriver.Chrome(chrome_options=chrome_options, executable_path='D:\\chromedriver')
self.browser = webdriver.Chrome(chrome_options=chrome_options)
self.wait = WebDriverWait(self.browser, 80)
self.browser.set_page_load_timeout(40)
self.searchId = searchId # 搜尋框的ID,用于定位
self.bowtonID = bowtonID # 點選按鈕的ID,用于定位
self.threshold = 60 # 驗證碼圖檔對比中RGB的內插補點,可調
self.left = 50 # 驗證碼圖檔的對比中的起始坐标,即拖動子產品的右邊線位置
self.deviation = 7 # 誤內插補點,這個值是多次測試得出的經驗值
self.page_count = []
def open(self):
"""
打開浏覽器,并輸入查詢内容
"""
self.browser.maximize_window()
self.browser.get(self.url)
if '無法通路此網站' in self.browser.page_source or '未連接配接到網際網路' in self.browser.page_source or '該網頁無法正常運作' in self.browser.page_source: # 判斷是否正常打開網頁
self.browser.quit()
keyword = self.wait.until(EC.presence_of_element_located((By.ID, self.searchId)))
bowton = self.wait.until(EC.presence_of_element_located((By.ID, self.bowtonID)))
try:
keyword.send_keys(self.word) # 發送關鍵詞
except:
keyword.send_keys(self.word)
try:
bowton.send_keys(Keys.ENTER) # 此處有坑!!!可能打開的視窗大小不同,導緻網頁上的元素重疊在一起,不能進行點選,是以直接進行Enter鍵進入
except:
bowton.send_keys(Keys.ENTER)
2,執行js,生成帶缺口和不帶缺口的驗證碼圖檔
def get_image(self):
"""
擷取驗證碼圖檔
:return: 驗證碼圖檔對象
"""
times = random.uniform(3, 5)
times = round(times, 2)
time.sleep(times)
bg_js = 'return document.getElementsByClassName("geetest_canvas_bg geetest_absolute")[0].toDataURL("image/png");' # 帶缺口驗證碼圖檔js
fullbg_js = 'return document.getElementsByClassName("geetest_canvas_fullbg geetest_fade geetest_absolute")[0].toDataURL("image/png");' # 完整驗證碼圖檔js
# 執行 JS 代碼并拿到圖檔 base64 資料
bg_info = self.browser.execute_script(bg_js) # 執行js檔案得到帶圖檔資訊的圖檔資料
bg_base64 = bg_info.split(',')[1] # 拿到base64編碼的圖檔資訊
bg_bytes = base64.b64decode(bg_base64) # 轉為bytes類型
bg_image = Image.open(BytesIO(bg_bytes)) # image讀取圖檔資訊
fullbg_info = self.browser.execute_script(fullbg_js) # 執行js檔案得到帶圖檔資訊的圖檔資料
fullbg_base64 = fullbg_info.split(',')[1] # 拿到base64編碼的圖檔資訊
fullbg_bytes = base64.b64decode(fullbg_base64) # 轉為bytes類型
fullbg_image = Image.open(BytesIO(fullbg_bytes)) # image讀取圖檔資訊
return bg_image,fullbg_image
3,拿到滑動驗證碼需要移動的距離
def get_distance(self,image1,image2):
"""
拿到滑動驗證碼需要移動的距離
:param image1: 沒有缺口的圖檔對象
:param image2: 帶缺口的圖檔對象
:return: 需要移動的距離
"""
i = 0
for i in range(self.left, image1.size[0]):
for j in range(image1.size[1]):
rgb1 = image1.load()[i, j]
rgb2 = image2.load()[i, j]
res1 = abs(rgb1[0] - rgb2[0])
res2 = abs(rgb1[1] - rgb2[1])
res3 = abs(rgb1[2] - rgb2[2])
if not (res1 < self.threshold and res2 < self.threshold and res3 < self.threshold):
distance = i -self.deviation
return distance
logging.debug('未識别出驗證碼中的不同位置,或圖檔定位出現異常')
return i # 如果沒有識别出不同位置,則象征性的滑動,以重新整理下一張驗證碼
4,生成滑動軌迹
這個軌迹是研究蠻久才出來的,因為極限驗證會通過使用者滑動軌迹的大資料,經過機器學習,來判定軌迹是機器滑動和人為滑動,之前網上先加速運動,再減速,什麼區間震蕩軌迹,剛開始還行,後面成功率就會越來越低,我的這個滑動軌迹至今還蠻穩定
def get_track(self,distance):
"""
:param distance:
:return: 滑動軌迹
"""
track = []
current = 0
mid = int(distance * round(random.uniform(0.6, 0.7), 2))
jiansu = distance - mid # 需要減速的距離
# 計算間隔
t = 0.2
# 初速度
v = 0
while current < distance:
if current < mid:
# 設定加速度動态變化
# Chrome 浏覽器的加速度
ap = random.uniform(3, 5)
times = round(ap, 2)
a = times
# 初速度v0
v0 = v
v = v0 + a * t
move = v0 * t + 1 / 2 * a * t * t + 0.5
# 目前位移
current += move
# 加入軌迹
track.append(round(move))
else:
a = -1 * (v * v) / (2 * jiansu) #減速的速度
v0 = v
v = v0 + a * t
if distance > 120:
move = v0 * t + 1 / 2 * a * t * t - 1.5 # 1.5,1,0.5都是噪聲,因為剛開始的減速距離挺大,為了盡量是最後的軌迹能夠到1,就加了一些噪聲
elif distance <= 120 and distance >= 60:
move = v0 * t + 1 / 2 * a * t * t - 1
else:
move = v0 * t + 1 / 2 * a * t * t - 0.5
if move < 1: # 減速運動如果後面move會越來越小,如果不讓小于1的固定為1的話,有時候會進死循環
move = 1
current += move
track.append(round(move))
return track
5,拖動滑塊到缺口處
def move_to_gap(self, slider, track):
"""
拖動滑塊到缺口處
:param slider: 滑塊
:param track: 軌迹
:return:
"""
ActionChains(self.browser).click_and_hold(slider).perform()
for x in track:
ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform()
time.sleep(0.5)
ActionChains(self.browser).release().perform()
6,傳回html
def check_html(self, html): # 檢測一些html,如果成功,就可以傳回html,不成功,就可以重試
if 'geetest_success_radar_tip_content' in html:
return True
else:
return False
結束語:
第一次寫部落格,學藝不精,往各位同仁不要見笑,希望能和各位多多交流,學無止境!!!上面隻寫了主要步驟,另外還有翻頁,重試等沒展示。在此申明,此部落格隻用于學習交流,不得進行非法用途!