YY點觸驗證碼識別案例
這個網站在第一次請求網站的時候,用selenium定位不到驗證碼,最后發現是iframe標簽的問題
我們需要再次請求iframe里面的鏈接,打開新的網頁之后就可以定位操作了。
1 # !/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 from chaojiying import Chaojiying 5 import random 6 import time 7 from PIL import Image 8 from io import BytesIO 9 from selenium import webdriver 10 from selenium.webdriver.support.ui import WebDriverWait 11 from selenium.webdriver import ActionChains 12 from selenium.webdriver.common.by import By 13 from selenium.webdriver.support import expected_conditions as ec 14 15 CHAOJIYING_NAME = '******' # 超級鷹賬號 16 CHAOJIYING_PWD = '********' # 超級鷹密碼 17 CHAOJIYING_ID = 894613 # 軟件ID 18 CHAOJIYING_KIND = 9004 # 驗證碼類型 19 20 21 class YYVerification(object): 22 """ 23 此類用於YY的驗證碼識別,可以應用到類似的驗證碼識別上,這種驗證碼類型是 24 點擊類驗證碼.這里我們是對接超級鷹平台。 25 """ 26 def __init__(self): 27 self.url = 'https://aq.yy.com/p/reg/account.do?appid=&url=&fromadv=udbclsd_r' 28 self.driver = webdriver.Chrome() 29 self.chaojiying = Chaojiying(CHAOJIYING_NAME, CHAOJIYING_PWD, CHAOJIYING_ID) 30 31 def __del__(self): 32 self.driver.close() 33 34 def screen_shot(self): 35 """ 36 網頁截屏 37 :return: bool值 38 """ 39 # self.driver.maximize_window() 40 time.sleep(2) 41 # # 用於網頁的向下滾動 42 # js = 'var q=document.documentElement.scrollTop=300' 43 # self.driver.execute_script(js) 44 # time.sleep(1) 45 self.driver.save_screenshot('yy.png') 46 return True 47 48 def i_url(self): 49 """ 50 實現對iframe標簽的url請求,並定位新網頁 51 :return: 定位對象 52 """ 53 i = self.driver.find_element_by_xpath('/html/body/div[2]/div[2]/div/iframe') 54 url_1 = i.get_attribute('src') 55 print(url_1) 56 self.driver.get(url_1) 57 wait = WebDriverWait(self.driver, 20) 58 element = wait.until(ec.presence_of_element_located((By.XPATH, '//*[@id="mPickWords"]/div[1]'))) 59 return element 60 61 def shear_location(self): 62 """ 63 計算對截屏剪切的坐標,注意這里不同電腦可能會修改start_x到end_y 64 后邊添加的數是根據作者的電腦優化的 65 :return: 返回坐標以及網頁剪切定位的對象 66 """ 67 time.sleep(random.random() + 1) 68 print('正在獲取div') 69 div = self.i_url() 70 start_x = div.location['x'] + 25 71 start_y = div.location['y'] + 65 72 end_x = div.location['x'] + 350 + 25 73 end_y = div.location['y'] + 218 + 65 74 result = (start_x, start_y, end_x, end_y) 75 print(result) 76 return result, div 77 78 @staticmethod 79 def shear_image(axis): 80 im = Image.open('yy.png') 81 new_image = im.crop(axis) 82 new_image.save('new_img.png') 83 return new_image 84 85 def upload_picture(self, img): 86 """ 87 上傳圖片(Byte),返回點擊的坐標。這里對返回的坐標進行了處理, 88 處理過程可以看成 shear_location 函數的坐標數據逆處理過程 89 :param img: 上傳的圖片 90 :return: 點擊坐標 91 """ 92 image = img 93 byte_array = BytesIO() 94 image.save(byte_array, format('PNG')) 95 # 提交圖片 96 result = self.chaojiying.post_pic(byte_array.getvalue(), CHAOJIYING_KIND) 97 print(result) 98 if '無可用題分' in result['err_str']: 99 print('題分已經不足請充值') 100 raise ValueError 101 pic_str = result['pic_str'] 102 pic_list = [[i for i in x.split(',')] for x in pic_str.split('|')] 103 for i in pic_list: 104 i[0] = int(int(i[0])*(282/354)) 105 i[1] = int(int(i[1])*(219/274)) 106 print(pic_list) 107 return pic_list 108 109 def click_now(self, coordinates, axis, element): 110 """ 111 這里如果驗證失敗會進行回調,實現驗證碼的自動驗證。 112 :param coordinates: 點擊坐標 113 :param axis: 剪切坐標 114 :param element: 剪切位置的定位 115 :return: 返回點擊的成功信息 116 """ 117 print('點擊開始') 118 print(coordinates) 119 for location in coordinates: 120 ActionChains(self.driver).move_to_element_with_offset(element, location[0], location[1]).click().perform() 121 time.sleep(random.random() + 1.8) 122 submission = self.driver.find_element_by_xpath('//*[@id="mPickWords"]/div[2]/span[4]') 123 submission.click() 124 time.sleep(1) 125 if 'pw_submit_disabled' in submission.get_attribute('class'): 126 return '點擊成功' 127 else: 128 time.sleep(2) 129 print('正在重新識別新的驗證碼') 130 self.revalidation(axis, element) 131 return '點擊成功' 132 133 def revalidation(self, axis, element): 134 """ 135 網頁跳轉之后,執行驗證的主程序 136 :param axis: 剪切坐標 137 :param element: 剪切位置的定位對象 138 :return: 驗證成果 139 """ 140 self.screen_shot() 141 if not self.screen_shot(): 142 return '截圖失敗' 143 time.sleep(1) 144 # 剪切圖片 145 new_image = self.shear_image(axis) 146 new_image.show() 147 # 上傳圖片並返回點擊坐標 148 click_coordinates = self.upload_picture(new_image) 149 # 點擊驗證碼 150 print(self.click_now(click_coordinates, axis, element)) 151 return '點擊驗證結束' 152 153 def main(self): 154 self.driver.get(self.url) 155 wait = WebDriverWait(self.driver, 20) 156 wait.until(ec.presence_of_element_located((By.XPATH, '/html/body/div[2]/div[2]/div/iframe'))) 157 axis, element = self.shear_location() 158 self.revalidation(axis, element) 159 160 161 if __name__ == '__main__': 162 yy = YYVerification() 163 yy.main()
