模拟登录哔哩哔哩

import time
from io import BytesIO
from PIL import Image
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
USERNAME = 'xxxx'
PASSWORD = 'xxxx'
BORDER = 6
class CrackGeetest():
def __init__(self):
self.url = 'https://passport.bilibili.com/login'
self.borwser = webdriver.Chrome()
self.wait = WebDriverWait(self.borwser,20)
self.username = USERNAME
self.password = PASSWORD

def open(self):
'''
输入账号和密码
:return:None
'''
self.borwser.get(self.url)
username = self.wait.until(EC.presence_of_element_located((By.ID,'login-username')))
password = self.wait.until(EC.presence_of_element_located((By.ID,'login-passwd')))
username.send_keys(self.username)
password.send_keys(self.password)

def login(self):
'''
获取登录按钮
:return: None
'''
button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'btn-login')))
button.click()

def get_position(self):
'''
获取验证码图片位置
:return: 元组
'''
img = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'geetest_canvas_img')))
time.sleep(2)
# 图片在浏览器的位置
location = img.location
#图片的大小
size = img.size
top,bottom,left,right = location['y'],location['y']+size['height'],location['x'],location['x']+size['width']
return (top,bottom,left,right)

def get_screenshot(self):
'''
网页截图
:return: 截图对象
'''
#页面快照
screenshot =self.borwser.get_screenshot_as_png()
#打开快照文件
screenshot = Image.open(BytesIO(screenshot))
return screenshot

def get_images(self,name='captcha.png'):
'''
获取验证码图片
:return:
'''
top,bottom,left,right = self.get_position()
print('验证码位置',(top,bottom,left,right))
screenshot = self.get_screenshot()
#截取验证码
captcha = screenshot.crop((left,top,right,bottom))
captcha.save(name)
return captcha

def delete_style(self):
'''
执行js脚本,获取无滑块图
:return:
'''
js='document.querySelectorAll("canvas")[3].style=""'
self.borwser.execute_script(js)

def get_gap(self, image1, image2):
'''
获取缺口偏移量
:param image1:有缺口
:param image2: 无缺口
:return: 偏移量
'''
left = 60
for i in range(left,image1.size[0]):
for j in range(image1.size[1]):
if not self.is_pixel_equal(image1,image2,i,j):
left = i
return left
return left


def is_pixel_equal(self, image1, image2, x, y):
"""
判断两个像素是否相同
:param image1: 图片1
:param image2: 图片2
:param x: 位置x
:param y: 位置y
:return: 像素是否相同
"""
#取两个像素的像素点
pixel1 = image1.load()[x,y]
pixel2 = image2.load()[x,y]
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 get_track(self, distance):
"""
根据偏移量获取移动轨迹
:param distance: 偏移量
:return: 移动轨迹
"""
#移动轨迹
track=[]
#当前位移
current = 0
#减速阈值
mid = distance * 4/5
#计算间隔
t = 0.2
#初速度
v = 0
while current <distance:
if current < mid:
#家速度为正2
a = 2
else:
a = -3
v0 = v
#当前速度
v = v0+a*t
# 移动距离
x = v0 * t +1/2 * a * t * t
#当前位移
current += x
#加入轨迹
track.append(round(x))
return track

def get_slider(self):
'''
获取滑块对象
:return: slider
'''
slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'geetest_slider_button')))
return slider
def move_to_gap(self, slider, track):
'''
滑动滑块
:param slider:滑块对象
:param track: 轨迹
:return:
'''
#点击滑块
ActionChains(self.borwser).click_and_hold(slider).perform()
#遍历轨迹移动滑块
for x in track:
ActionChains(self.borwser).move_by_offset(xoffset=x,yoffset=0).perform()
time.sleep(0.5)
#松开滑块
ActionChains(self.borwser).release().perform()

def crack(self):
#输入账号密码
self.open()
#点击登录按钮
self.login()
#获取缺口照片
image1 =self.get_images('captcha1.png')
#获取原图
self.delete_style()
image2 = self.get_images('captcha2.png')
#获取缺口位置
gap = self.get_gap(image1,image2)
print('缺口位置', gap)
# 减去缺口位移
gap -= BORDER
#获取轨迹
tack = self.get_track(gap)
#滑动滑块
slider =self.get_slider()
self.move_to_gap(slider,tack)


if __name__ == '__main__':
crack = CrackGeetest()
crack.crack()


当我寻找登录按钮,网页中是btn btn-login 我查找这个一找不到 改成btn-login成功了 图片位置也同理
这个虽然成功登录 ,但有时会时间过长 而超时 还有修改的空间

猜你喜欢

转载自www.cnblogs.com/kill-520/p/11642719.html