python+selenium实现B站模拟登陆

首先是找出登录界面各控件的位置,我尝试从网页源代码寻找,但找不到,网上也没有很好的讲解,经过多次尝试发现了寻找控件的方法.
即网页的检查功能。
打开检查界面后可看到如下图像:
在这里插入图片描述
从…中即可对应左侧UI找出各控件的位置与id等信息。如下图:
在这里插入图片描述
下面进行登陆代码的书写:

    def login(self):
        driver = webdriver.Firefox()
        driver.get(self.url)
        driver.find_element_by_id('login-username').send_keys(self.username) #输入账号
        driver.find_element_by_id('login-passwd').send_keys(self.password) #输入密码
        driver.find_element_by_class_name('btn-login').click()

但因为被检测为机器人无法出现滑动验证界面。后来经过查阅资料得知可以通过在定位控件后sleep()来模拟人的操作,进而成功得出滑动验证界面。

 def login(self):
        driver = webdriver.Firefox()
        driver.get(self.url)
        driver.find_element_by_id('login-username').send_keys(self.username) #输入账号
        driver.find_element_by_id('login-passwd').send_keys(self.password) #输入密码
        button = driver.find_element_by_class_name('btn-login')
        time.sleep(1)
        button.click()

接下来是滑块验证的部分,主要参考这篇博客的方法。
这里用到的图像处理包image需要导入包PIL,但python3.6不能导入PIL,需要导入Pillow后使用。pillow的导入可以下载后安装(下载网址)。
下面附上全部代码:

# coding=utf-8
from PIL import Image

import requests
from selenium import webdriver
import time

from selenium.webdriver import ActionChains


class loginbli(object):
    def __init__(self): #初始化一些信息
       self.left = 70  # 定义一个左边的起点 缺口一般离图片左侧有一定的距离 有一个滑块
       self.url = 'https://passport.bilibili.com/login'
       self.username = ''
       self.password = ''
       self.driver = webdriver.Firefox()
    def login(self):
        self.driver.get(self.url)
        self.driver.maximize_window()
        self.driver.find_element_by_id('login-username').send_keys(self.username) #输入账号
        self.driver.find_element_by_id('login-passwd').send_keys(self.password) #输入密码
        button = self.driver.find_element_by_class_name('btn-login')
        time.sleep(1)
        button.click()
        time.sleep(1)
    def getimg(self): #获得验证图片及完整图片
        img = self.driver.find_element_by_class_name('geetest_canvas_bg')
        time.sleep(1)
        img.screenshot('E:\\img1.png')
        js = 'var change = document.getElementsByClassName("geetest_canvas_fullbg");change[0].style = "display:block;"'
        self.driver.execute_script(js)
        time.sleep(1)
        img2 = self.driver.find_element_by_class_name('geetest_canvas_fullbg')
        time.sleep(1)
        img2.screenshot('E:\\img2.png')

    def is_similar(self, image1, image2, x, y):
        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_diff_location(self):  # 获取缺口图起点
        captcha1 = Image.open('E:\\img1.png')
        captcha2 = Image.open('E:\\img2.png')
        for x in range(self.left, captcha1.size[0]):  # 从左到右 x方向
            for y in range(captcha1.size[1]):  # 从上到下 y方向
                if not self.is_similar(captcha1, captcha2, x, y):
                    return x  # 找到缺口的左侧边界 在x方向上的位置

    def get_move_track(self, gap):
            track = []  # 移动轨迹
            current = 0  # 当前位移
            # 减速阈值
            mid = gap * 4 / 5  # 前4/5段加速 后1/5段减速
            t = 0.2  # 计算间隔
            v = 0  # 初速度
            move = 0
            while current < gap  and current + move < gap:
                if current < mid:
                    a = 3  # 加速度为+3
                else:
                    a = -3  # 加速度为-3
                v0 = v  # 初速度v0
                v = v0 + a * t  # 当前速度
                move = v0 * t + 1 / 2 * a * t * t  # 移动距离
                current += move  # 当前位移
                track.append(round(move))  # 加入轨迹
            move = gap - current
            track.append(round(move))
            return track

    def move_slider(self, track):
        slider = self.driver.find_element_by_class_name('geetest_slider_button')
        ActionChains(self.driver).click_and_hold(slider).perform()
        time.sleep(1)
        y = 0
        for x in track:  # 只有水平方向有运动 按轨迹移动
            ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform()
            y += x
        time.sleep(1)
        ActionChains(self.driver).release().perform()  # 松开鼠标





log = loginbli()
log.login()
log.getimg()
gap = log.get_diff_location()#缺口左起点位置
gap = gap -10
# 减去滑块左侧距离图片左侧在x方向上的距离 即为滑块实际要移动的距离
track = log.get_move_track(gap)
print("移动轨迹",track)
log.move_slider(track)

本代码是在FireFox上进行的,大部分时候滑块能成功滑到正确位置,但会被判定为机器人,所以此算法仍需优化,仅用于练习和初学使用。
注:需要把电脑显示比例调为100%。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值