使用Selenium破解新浪微博的四宮格驗(yàn)證碼
在我們爬蟲(chóng)的時(shí)候經(jīng)常會(huì)遇到驗(yàn)證碼,新浪微博的驗(yàn)證碼是四宮格形式。
可以采用模板驗(yàn)證碼的破解方式,也就是把所有驗(yàn)證碼的情況全部列出來(lái),然后拿驗(yàn)證碼的圖片和這所有情況中的圖片進(jìn)行對(duì)比,然后獲取驗(yàn)證碼,再通過(guò)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):
"""
打開(kāi)網(wǎng)頁(yè)輸入用戶(hù)名密碼登錄
: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)頁(yè)截圖轉(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()將圖片裁剪出來(lái),后面需要一個(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:
# 松開(kāi)鼠標(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)證碼圖片過(guò)時(shí)了,重新開(kāi)啟圖片收集程序,運(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):
"""
打開(kāi)網(wǎng)頁(yè)輸入用戶(hù)名密碼登錄
: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)頁(yè)截圖轉(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()將圖片裁剪出來(lái),后面需要一個(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模塊模擬瀏覽器抓取斗魚(yú)直播間信息示例
- Python使用Selenium模塊實(shí)現(xiàn)模擬瀏覽器抓取淘寶商品美食信息功能示例
- Python+selenium實(shí)現(xiàn)自動(dòng)循環(huán)扔QQ郵箱漂流瓶
- Python使用selenium實(shí)現(xiàn)網(wǎng)頁(yè)用戶(hù)名 密碼 驗(yàn)證碼自動(dòng)登錄功能
- Python Selenium Cookie 繞過(guò)驗(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庫(kù)matplotlib繪制坐標(biāo)圖
這篇文章主要為大家介紹了python庫(kù)matplotlib繪制坐標(biāo)圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10
簡(jiǎn)單介紹Python中的readline()方法的使用
這篇文章主要介紹了簡(jiǎn)單介紹Python中的readline()方法的使用,是Python入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-05-05
python爬蟲(chóng)指南之xpath實(shí)例解析(附實(shí)戰(zhàn))
在進(jìn)行網(wǎng)頁(yè)抓取的時(shí)候,分析定位html節(jié)點(diǎn)是獲取抓取信息的關(guān)鍵,目前我用的是lxml模塊,下面這篇文章主要給大家介紹了關(guān)于python爬蟲(chóng)指南之xpath實(shí)例解析的相關(guān)資料,需要的朋友可以參考下2022-01-01
Python wordcloud庫(kù)安裝方法總結(jié)
在本篇文章里小編給大家整理的是一篇關(guān)于Python wordcloud庫(kù)安裝方法總結(jié)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。2020-12-12
使用python實(shí)現(xiàn)一個(gè)瀏覽器自動(dòng)化的腳本
最近工作中有這樣一個(gè)需求:客戶(hù)反饋在瀏覽器操作過(guò)程中,重復(fù)流程操作太頻繁,能不能讓瀏覽器自動(dòng)操作完成?所以本文給大家介紹了如何使用python實(shí)現(xiàn)一個(gè)瀏覽器自動(dòng)化的腳本,感興趣的朋友可以參考下2024-04-04

