selenium 實現點觸驗證碼識別


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()

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM