'''
极验验证码
1.抠图片
1)带有缺口的图片
2)不带缺口的图片
2.比较两张图片的像素,获取移动距离
3.拖拽
'''
import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from PIL import Image
from io import BytesIO
class Bispider():
def __init__(self):
self.browser = webdriver.Chrome()
self.username = '自己随便想一个账号'
self.password = '自己随便想一个密码'
#显示等待
self.wait = WebDriverWait(self.browser,50)
#哔哩哔哩登录界面的路由
self.url = 'https://passport.bilibili.com/login'
self.bigimgname1 = 'screen1.png'
self.bigimgname2 = 'screen2.png'
self.samllpig1 = 's1.png'
self.samllpig2 = 's2.png'
def open(self):
#打开浏览器
self.browser.get(self.url)
# 获取账号的输入框并输入内容
input = self.wait.until(
EC.presence_of_element_located((By.XPATH,'//*[@id="login-username"]'))
)
input.clear()
input.send_keys(self.username)
# 获取密码的输入框并输入内容
pwd_input = self.wait.until(
EC.presence_of_element_located((By.XPATH,'//*[@id="login-passwd"]'))
)
pwd_input.clear()
pwd_input.send_keys(self.password)
#获取登录按钮,实现点击
button = self.wait.until(
EC.element_to_be_clickable((By.XPATH,'//*[@id="geetest-wrap"]/ul/li[5]/a[1]'))
)
button.click()
time.sleep(2)
#获取验证码元素的位置
def get_position(self):
code = self.wait.until(
EC.presence_of_element_located((By.XPATH,'/html/body/div[2]/div[2]/div[6]/div/div[1]/div[1]/div/a/div[1]/div/canvas[1]'))
)
location = code.location
size = code.size
x1 = location['x']
y1 = location['y']
x2 = x1 + size['width']
y2 = y1 + size['height']
return x1,y1,x2,y2
def screen_png(self,name,sname):
#将小图块屏蔽掉
js = 'document.getElementsByClassName("geetest_canvas_slice")[0].style.display="none"'
self.browser.execute_script(js)
#获取整个页面的图片
big1 = self.browser.get_screenshot_as_png()
img1 = Image.open(BytesIO(big1))
img1.save(name)
# 抠出验证码的小图(小图的位置)
x1,y1,x2,y2 = self.get_position()
img2 = img1.crop((x1,y1,x2,y2))
img2.save(sname)
return img2
def screen_png_new(self,name,sname):
js = 'document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display="block"'
self.browser.execute_script(js)
# time.sleep(2)
img2 = self.screen_png(name,sname)
return img2
def is_xaingshi(self,img1,img2,x,y):
#判断两张图片同一像素点,是否相似
a = img1.load()[x,y]
b = img2.load()[x,y]
c = 60
if abs(a[0]-b[0]) < c and abs(a[1] - b[1]) < c and \
abs(a[2] - b[2]) < c and abs(a[3]-b[3]) < c:
return True
return False
def get_distance(self,img1,img2):
for x in range(img1.size[0]):
for y in range(img1.size[1]):
#判断两张图片的像素是否一致
if not self.is_xaingshi(img1,img2,x,y):
return x
return 0
def tuozuai(self,distance):
js = 'document.getElementsByClassName("geetest_canvas_slice")[0].style.display="block"'
self.browser.execute_script(js)
tuo = self.wait.until(
EC.presence_of_element_located((By.XPATH, '/html/body/div[2]/div[2]/div[6]/div/div[1]/div[2]/div[2]'))
)
ActionChains(self.browser).click_and_hold(tuo).perform()
ActionChains(self.browser).move_by_offset(xoffset=distance, yoffset=0).perform()
#释放鼠标
ActionChains(self.browser).release().perform()
def start(self):
#1.打开浏览器,模拟输入账号密码并点击登录
self.open()
#2.截取整张大图,然后抠出验证码的小图
img1 = self.screen_png(self.bigimgname1,self.samllpig1)
#3.修改背景图的样式,display: block,然后实现抠图功能
img2 = self.screen_png_new(self.bigimgname2,self.samllpig2)
#4.获取两张图片之间的距离
distince = self.get_distance(img1,img2)
print('移动距离为%s'% distince)
self.tuozuai(distince-6.5)
if __name__ == '__main__':
spider = Bispider()
spider.start()
哔哩哔哩验证码的破解
最新推荐文章于 2024-08-07 19:24:06 发布