使用Selenium破解新浪微博的四宮格驗(yàn)證碼
在我們爬蟲的時(shí)候經(jīng)常會(huì)遇到驗(yàn)證碼,新浪微博的驗(yàn)證碼是四宮格形式。
可以采用模板驗(yàn)證碼的破解方式,也就是把所有驗(yàn)證碼的情況全部列出來,然后拿驗(yàn)證碼的圖片和這所有情況中的圖片進(jìn)行對(duì)比,然后獲取驗(yàn)證碼,再通過selenium自動(dòng)拖拽點(diǎn)擊,進(jìn)行破解。
我們將驗(yàn)證碼四個(gè)點(diǎn)標(biāo)注為1234,那么所有的情況就是以下24種情況。
數(shù)字代表箭頭指向:
1234 | 2134 | 3124 | 4321 |
1243 | 2143 | 3142 | 4312 |
1342 | 2314 | 3214 | 4123 |
1324 | 2341 | 3241 | 4132 |
1423 | 2413 | 3412 | 4213 |
1432 | 2431 | 3421 | 4231 |
所有的情況就是以上24種。我們將這24中驗(yàn)證碼的情況放在一個(gè)文件夾內(nèi),當(dāng)我們?cè)诘卿浀臅r(shí)候用獲取的驗(yàn)證碼截圖去和所有的情況一一對(duì)比,然后獲取完全相同的驗(yàn)證碼,進(jìn)行點(diǎn)擊即可。代碼如下:
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException from selenium.webdriver.common.action_chains import ActionChains import time from PIL import Image from io import BytesIO from os import listdir USERNAME = '' PASSWORD = '' class CrackWeiboSlide(): def __init__(self): self.url = 'https://passport.weibo.cn/signin/login' self.browser = webdriver.Chrome() self.wait = WebDriverWait(self.browser,20) self.username = USERNAME self.password = PASSWORD def __del__(self): self.browser.close() def open(self): """ 打開網(wǎng)頁輸入用戶名密碼登錄 :return: None """ self.browser.get(self.url) username = self.wait.until(EC.presence_of_element_located((By.ID,'loginName'))) password = self.wait.until(EC.presence_of_element_located((By.ID,'loginPassword'))) submit = self.wait.until(EC.element_to_be_clickable((By.ID, 'loginAction'))) username.send_keys(self.username) password.send_keys(self.password) submit.click() def get_position(self): """ 獲取驗(yàn)證碼的位置 :return: 位置 """ try: img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,'patt-shadow'))) except TimeoutException: print('未出現(xiàn)驗(yàn)證碼') self.open() time.sleep(2) location = img.location size = img.size top=location['y'] bottom = location['y']+size['height'] left = location['x'] right = location['x']+size['width'] return (top,bottom,left,right) def get_screenshot(self): """ 獲取截圖 :return:截圖 """ screentshot = self.browser.get_screenshot_as_png() # BytesIO將網(wǎng)頁截圖轉(zhuǎn)換成二進(jìn)制 screentshot = Image.open(BytesIO(screentshot)) return screentshot def get_image(self,name): """獲取驗(yàn)證碼圖片""" top,bottom,left,right = self.get_position() print('驗(yàn)證碼位置',top,bottom,left,right) screenshot = self.get_screenshot() # crop()將圖片裁剪出來,后面需要一個(gè)參數(shù) captcha = screenshot.crop((left,top,right,bottom)) captcha.save(name) return captcha def detect_image(self,image): """ 匹配圖片 :param self: :param image: 圖片 :return: 拖動(dòng)順序 """ # 圖片所在的文件夾 for template_name in listdir('templates/'): print('正在匹配',template_name) template = Image.open('templates/'+template_name) # 匹配圖片 if self.same_img(image,template): # 將匹配到的文件名轉(zhuǎn)換為列表 numbers = [int(number)for number in list(template_name.split('.')[0])] print('拖動(dòng)順序',numbers) return numbers def is_pixel_equal(self,image1,image2,x,y): """ 判斷兩個(gè)像素的相似度 :param image1: 圖片1 :param image2: 圖片2 :param x: 位置x :param y: 位置y :return: 像素是否相同 """ # 取像素點(diǎn) pixel1 = image1.load()[x,y] pixel2 = image2.load()[x,y] # 偏差量等于60 threshold = 60 if abs(pixel1[0]-pixel2[0]) < threshold and abs(pixel1[1]-pixel2[1])<threshold and abs(pixel1[2]-pixel2[2])<threshold: return True else: return False def same_img(self,image,template): """ 識(shí)別相似的驗(yàn)證碼 :param image: 準(zhǔn)備識(shí)別的驗(yàn)證碼 :param template: 模板 :return: """ # 相似度閾值 threshold = 0.99 count = 0 # 匹配所有像素點(diǎn) for x in range(image.width): for y in range(image.height): # 判斷像素 if self.is_pixel_equal(image,template,x,y): count+=1 result = float(count)/(image.width*image.height) if result>threshold: print('成功匹配') return True return False def move(self,numbers): """ 根據(jù)順序拖動(dòng),此處接收的參數(shù)為前面的驗(yàn)證碼的順序列表 :param numbers: :return: """ # 獲取四宮格的四個(gè)點(diǎn) circles = self.browser.find_elements_by_css_selector('.patt-wrap .patt-circ') print('-----------------',circles) dx = dy =0 for index in range(4): circle = circles[numbers[index]-1] if index == 0: # 點(diǎn)擊第一個(gè)點(diǎn) ActionChains(self.browser).move_to_element_with_offset(circle,circle.size['width']/2,circle.size['height']/2).click_and_hold().perform() else: # 慢慢移動(dòng) times = 30 for i in range(times): ActionChains(self.browser).move_by_offset(dx/times,dy/times).perform() time.sleep(1/times) if index == 3: # 松開鼠標(biāo) ActionChains(self.browser).release().perform() else: # 計(jì)算下次的偏移 dx = circles[numbers[index+1]-1].location['x'] - circle.location['x'] dy = circles[numbers[index+1]-1].location['y'] - circle.location['y'] def crack(self): """ 破解入口 :return: """ self.open() # 獲取驗(yàn)證碼圖片 image = self.get_image('captcha.png') numbers = self.detect_image(image) self.move(numbers) time.sleep(10) print('識(shí)別結(jié)束') if __name__ == '__main__': crack = CrackWeiboSlide() crack.crack()
設(shè)置自己的賬號(hào)密碼即可實(shí)現(xiàn)。
有時(shí)候會(huì)匹配不上,圖片相似度閾值達(dá)不到0.99以上,這個(gè)時(shí)候可能是我們收集的驗(yàn)證碼圖片過時(shí)了,重新開啟圖片收集程序,運(yùn)行收集一下即可。
收集圖片程序代碼如下:
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException import time from PIL import Image from io import BytesIO from os import listdir USERNAME = '18239831004' PASSWORD = 'qweqweqwe' class CrackWeiboSlide(): def __init__(self): self.url = 'https://passport.weibo.cn/signin/login' self.browser = webdriver.Chrome() self.wait = WebDriverWait(self.browser,20) self.username = USERNAME self.password = PASSWORD def __del__(self): self.browser.close() def open(self): """ 打開網(wǎng)頁輸入用戶名密碼登錄 :return: None """ self.browser.get(self.url) username = self.wait.until(EC.presence_of_element_located((By.ID,'loginName'))) password = self.wait.until(EC.presence_of_element_located((By.ID,'loginPassword'))) submit = self.wait.until(EC.element_to_be_clickable((By.ID, 'loginAction'))) username.send_keys(self.username) password.send_keys(self.password) submit.click() def get_position(self): """ 獲取驗(yàn)證碼的位置 :return: 位置 """ try: img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME,'patt-shadow'))) except TimeoutException: print('未出現(xiàn)驗(yàn)證碼') self.open() time.sleep(2) location = img.location size = img.size top=location['y'] bottom = location['y']+size['height'] left = location['x'] right = location['x']+size['width'] return (top,bottom,left,right) def get_screenshot(self): """ 獲取截圖 :return:截圖 """ screentshot = self.browser.get_screenshot_as_png() # BytesIO將網(wǎng)頁截圖轉(zhuǎn)換成二進(jìn)制 screentshot = Image.open(BytesIO(screentshot)) return screentshot def get_image(self,name): """獲取驗(yàn)證碼圖片""" top,bottom,left,right = self.get_position() print('驗(yàn)證碼位置',top,bottom,left,right) screenshot = self.get_screenshot() # crop()將圖片裁剪出來,后面需要一個(gè)參數(shù) captcha = screenshot.crop((left,top,right,bottom)) captcha.save(name) return captcha # 獲取所有的驗(yàn)證碼 def main(self): count = 0 while True: name = str(count)+'.png' self.open() self.get_image(name) count+=1 if __name__ == '__main__': crack = CrackWeiboSlide() crack.main()
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
- Python+selenium 獲取瀏覽器窗口坐標(biāo)、句柄的方法
- selenium+python實(shí)現(xiàn)自動(dòng)化登錄的方法
- selenium+python實(shí)現(xiàn)1688網(wǎng)站驗(yàn)證碼圖片的截取功能
- Python使用Selenium模塊模擬瀏覽器抓取斗魚直播間信息示例
- Python使用Selenium模塊實(shí)現(xiàn)模擬瀏覽器抓取淘寶商品美食信息功能示例
- Python+selenium實(shí)現(xiàn)自動(dòng)循環(huán)扔QQ郵箱漂流瓶
- Python使用selenium實(shí)現(xiàn)網(wǎng)頁用戶名 密碼 驗(yàn)證碼自動(dòng)登錄功能
- Python Selenium Cookie 繞過驗(yàn)證碼實(shí)現(xiàn)登錄示例代碼
- SpringBoot優(yōu)化啟動(dòng)速度的方法實(shí)現(xiàn)
- python+selenium識(shí)別驗(yàn)證碼并登錄的示例代碼
- Python+Selenium+PIL+Tesseract自動(dòng)識(shí)別驗(yàn)證碼進(jìn)行一鍵登錄
相關(guān)文章
Python實(shí)現(xiàn)RGB等圖片的圖像插值算法
這篇文章主要介紹了通過Python實(shí)先圖片的以下三種插值算法:最臨近插值法、線性插值法以及雙線性插值法。感興趣的小伙伴們可以了解一下2021-11-11解決python調(diào)用自己文件函數(shù)/執(zhí)行函數(shù)找不到包問題
這篇文章主要介紹了解決python調(diào)用自己文件函數(shù)/執(zhí)行函數(shù)找不到包問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-06-06python GUI庫(kù)圖形界面開發(fā)之PyQt5信號(hào)與槽基本操作
這篇文章主要介紹了python GUI庫(kù)圖形界面開發(fā)之PyQt5信號(hào)與槽基本操作,需要的朋友可以參考下2020-02-02python正則表達(dá)式中匹配次數(shù)與貪心問題詳解(+??*)
正則表達(dá)式是一個(gè)特殊的字符序列,它能幫助你方便的檢查一個(gè)字符串是否與某種模式匹配,下面這篇文章主要給大家介紹了關(guān)于python正則表達(dá)式中匹配次數(shù)與貪心問題(+??*)的相關(guān)資料,需要的朋友可以參考下2022-10-10Tensorflow 模型轉(zhuǎn)換 .pb convert to .lite實(shí)例
今天小編就為大家分享一篇Tensorflow 模型轉(zhuǎn)換 .pb convert to .lite實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-02-02PyCharm搭建Spark開發(fā)環(huán)境實(shí)現(xiàn)第一個(gè)pyspark程序
這篇文章主要介紹了PyCharm搭建Spark開發(fā)環(huán)境實(shí)現(xiàn)第一個(gè)pyspark程序,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06