zoukankan      html  css  js  c++  java
  • python 奇淫技巧之自动登录 哔哩哔哩

    前言

      嘿,各位小伙伴好呀,今天要带来点什么干货呢,就从我的实际开发中来给大家带来一个案例吧,如何自动登录 哔哩哔哩

    接到老大通知,让我自动写一个自动登录 哔哩哔哩 的脚本,我当然是二话不说直接开怼,咱们的准则是啥,生死看淡,不服就干,干就完了,然而,现实总是被无情打脸,但是不管怎样,终究算是干过它了,下面我们来一一讲解,如何自动登录 哔哩哔哩

    准备工作

      chromedriver:浏览器驱动,可以理解为一个没有界面的chrome浏览器

      selenium:用于模拟人对浏览器进行点击、输出、拖拽等操作,就相当于是个人在使用浏览器,也常常用来应付反爬虫措施

     

    开始进行

      哔哩哔哩登录URL:https://passport.bilibili.com/login

      点击登录如下,自动登录blbl最难的一点就是,拖动滑块,对准缺口,正是这一个问题,让我掉了好几根头发,跟上我的脚步,能少踩一个一个坑是一个坑

     

     

     

      可能看到这,稍微会点技术的小伙伴都知道,其实我们根本要解决的问题,就是缺口获取缺口的位置,但是要怎么获取这个缺口的位置呢

     

     

     

     

     

      这尼玛,canvas是个啥,其实当时我和你们想法一样,其实呢,这个canvas是个画布,可不是图片,这咋办,这不是图片怎么办呢

      再说,我怎么知道哪个是带缺口图的canvas,经过多次测试,终于算是弄清楚了哪个是背景图,哪个是滑块,我来给大家标注一下

     

     

      So,问题又来了,我怎么获取这里面的图片呢,上图!!!

      我们先在游览器前端控制台,通过js代码,选中带缺口的标签,因为是类选中,所以需要取0下标,通过 toDataURL("image/png") 方法,将canvas将里面的图片转为base64位图片,转成base64位图片有啥用呢,来,我们赋值这么这么长的一段base64地址,复制到游览器中

      看到了没,我们梦寐已久带缺口的图片

      下一步怎么办呢,当时我的想法是,如法炮制,获取滑块的的图片,通过opencv模板对比,获取缺口位置,事实证明,我又被打脸,我们来看一下滑块图片张啥样

      是不是看着没什么问题,我们来保存本地试一下

      看出来了没,其实除了滑块以外,其他位置为透明区域,如果有透明区域,是不能通过opencv 模板对比的,这咋办,如果在用opencv处理图像,就是个累活了

      本着能懒就懒得原则,直接上第三方平台吧

      本文使用的第三方平台 联众:https://www.jsdati.com/

      这个平台还是比较贴心的,还有qq客服,有问题我们还可以问qq客服,暖心

      图像类型ID 1318为滑块验证码,只需要把带有缺口的图片上传到此网站就好

      各位小伙伴自行去联众注册哈,价格还挺香,1元100点,滑动验证码一个2点

      具体怎么操作呢,说了这么多,我们也该上代码了

    import base64
    import requests
    from selenium import webdriver
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    from selenium.webdriver import ActionChains
    import time
    import random
    
    # 联众打码平台账号密码
    api_username = "username"
    api_password = "password"
    file_name = "bg.png"
    api_post_url = "http://v1-http-api.jsdama.com/api.php?mod=php&act=upload"
    yzm_min = "1"
    yzm_max = "1"
    yzm_type = "1318"
    tools_token = ""
    
    
    # 初始化
    def init():
        # 定义为全局变量,方便其他模块使用
        global url, browser, username, password, wait
        # 登录界面的url
        url = 'https://passport.bilibili.com/login'
        # 实例化一个chrome浏览器
        browser = webdriver.Chrome(r"G:installPagechromedriver_win32 _78.0.3904.70chromedriver.exe")
        browser.maximize_window()
        time.sleep(2)
        # 用户名
        username = 'qweqwe'
        # 密码
        password = 'asdfasdf'
        # 设置等待超时
        wait = WebDriverWait(browser, 20)
    
    
    # 登录
    def login():
        # 打开登录页面
        browser.get(url)
        # 获取用户名输入框
        user = wait.until(EC.presence_of_element_located((By.ID, 'login-username')))
        # 获取密码输入框
        passwd = wait.until(EC.presence_of_element_located((By.ID, 'login-passwd')))
        # 输入用户名
        user.send_keys(username)
        # 输入密码
        passwd.send_keys(password)
    
        # 获取登录按钮
        login_btn = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'a.btn.btn-login')))
        # 随机延时点击
        time.sleep(random.random() * 5)
        login_btn.click()
        time.sleep(2)
    
    
    # 下载 带缺口的背景图
    def downfile():
        # 下面的js代码根据canvas文档说明而来
        JS = 'return document.getElementsByClassName("geetest_canvas_bg geetest_absolute")[0].toDataURL("image/png")'
        # 执行 JS 代码并拿到图片 base64 数据
        im_info = browser.execute_script(JS)  # 执行js文件得到带图片信息的图片数据
        im_base64 = im_info.split(',')[1]  # 拿到base64编码的图片信息
        im_bytes = base64.b64decode(im_base64)  # 转为bytes类型
        with open('bg.png', 'wb') as f:  # 保存图片到本地
            f.write(im_bytes)
    
    
    # 获取 缺口图片位置坐标
    def get_geetest_postion():
        headers = {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
            'Accept-Encoding': 'gzip, deflate',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0',
            'Connection': 'keep-alive',
            'Host': 'v1-http-api.jsdama.com',
            'Upgrade-Insecure-Requests': '1'
        }
    
        files = {
            'upload': (file_name, open(file_name, 'rb'), 'image/png')
        }
    
        data = {
            'user_name': api_username,
            'user_pw': api_password,
            'yzm_minlen': yzm_min,
            'yzm_maxlen': yzm_max,
            'yzmtype_mark': yzm_type,
            'zztool_token': tools_token
        }
        s = requests.session()
        r = s.post(api_post_url, headers=headers, data=data, files=files, verify=False)
        print(r.json(), type(r.json()))
        postion = r.json().get("data").get("val")  # type:str
        x, y = postion.split(",")
        # print(x,y)
        return int(x)
    
    
    # 构造滑动轨迹
    def get_track(distance):
        track = []
        current = 0
        mid = distance * 3 / 4
        t = 0.2
        v = 0
        while current < distance:
            if current < mid:
                a = 2
            else:
                a = -3
            v0 = v
            v = v0 + a * t
            move = v0 * t + 1 / 2 * a * t * t
            current += move
            track.append(round(move))
        return track
    
    
    # 模拟拖动
    def move_to_gap(trace):
        # 得到滑块标签
    
        slider = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div.geetest_slider_button')))
    
        ActionChains(browser).click_and_hold(slider).perform()
        for x in trace:
            # 使用move_by_offset()方法拖动滑块,perform()方法用于执行
            ActionChains(browser).move_by_offset(xoffset=x, yoffset=0).perform()
        # 模拟人类对准时间
        time.sleep(0.1)
        # 释放滑块
        ActionChains(browser).pause(0.5).release().perform()
    
    
    # 拖动滑块
    def slide():
        distance = get_geetest_postion()
        print('计算偏移量为:%s Px' % distance)
        # 计算移动轨迹
        trace = get_track(distance - 10)
        # 移动滑块
        move_to_gap(trace)
    
    
    if __name__ == '__main__':
        init()
        login()
        downfile()
        slide()
    查看代码

    效果展示

     

  • 相关阅读:
    servlet程序开发
    jsp九大内置对象
    git原理教程
    jsp基础语法_Scriptlet_基本指令
    06_mysql多表查询
    05_mysql单表查询
    04_mysql增删改操作
    03_mysql索引的操作
    01_mysql数据库操作和基本数据类型
    生成器
  • 原文地址:https://www.cnblogs.com/HeavyShield/p/12115812.html
Copyright © 2011-2022 走看看