selenium实例:自动刷青马网课实现登陆 python实现自动登陆 利用pytesseract自动识别验证码并登录

准备工作

首先得先安装好python,IDE,selenium,Firefox浏览器
这里可以供参考
Windows下的python的安装全步骤,分图详解
Windows+Firefox(Chrome)+selenium+python配置并更改源(加快下载速度,不然很慢)
安装相关的库
pip install 相关库的名称即可
一般来说,需要检查time,pytesseract,PIL等库是否被正确安装
如果出现报错,安装上相应的库即可
推荐使用anconda进行
不用也可,测试环境在安装好selenium的anconda下进行
注意,原本的anconda并没有包括selenium库,需要自行安装
另外,我们还需要Tesseract-OCR这个软件,用于ocr识别相关验证码
关于这个软件的信息请自行百度
总的来说,为了运行这个实例,你需要:
1.一台装有Windows的电脑和网络
2.python3及其IDE(如pycharm,vscode等),最好是anconda
3.相关的python库,如PIL,selenium等
4.运行ocr所需要的软件Tesseract-OCR
5.Firefox浏览器及其对应webdriver

相关功能的实现

import pytest
import time
import json
import pytesseract
import re
import requests
import pyautogui

from time import sleep
from PIL import Image,ImageEnhance,ImageOps
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver import FirefoxOptions
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary

class Class:
    #该函数功能是初始化
    def __init__(self,un,pw,cbe,cen):
        opts = FirefoxOptions()
        # opts.add_argument("--headless")
        option_profile = webdriver.FirefoxProfile()
        option_profile.set_preference("plugin.state.flash",2)
        option_profile.set_preference("security.insecure_field_warning.contextual.enabled",False)
        #上面的部分是对浏览器的设置,使flash能自动播放
        self.driver = webdriver.Firefox(firefox_profile=option_profile,options=opts)
        self.driver.get('http://hnqmgc.17el.cn/')
        self.driver.set_window_size(1920,1080)
        #创建一个浏览器对象并打开网站,设置窗口尺寸为1920*1080
        self.un=un
        self.pw=pw
        self.cbe=cbe
        self.cen=cen
        #接收传入的un用户名,pw密码,cbe课程开始刷的id,cen课程结束刷的id
        print('初始化浏览器成功')

    #该函数功能是处理验证码
    def processing_pictures(self):
        sleep(1)
        self.driver.find_element(By.ID, "code").click()
        sleep(1)
        #找到验证码,点一下刷新验证码。因为这个函数在一个循环体,一次可能不能登录成功。
        self.driver.save_screenshot('pictures.png')
        #保存网页截图
        left=1365
        top=319
        right=1365+48
        bottom=319+18
        #上面的是验证码的坐标
        imge=Image.open("pictures.png").crop((left, top, right, bottom))
        #imge.show() 作用是运行时检查错误用的,把处理后的图像输出
        img = imge.convert("L")
        #图片转灰度,由于这个验证码太脑残,不需要进行插值等特殊处理
        pixdata = img.load()
        w, h = img.size
        threshold = 160
        # img.show()
        for y in range(h):
            for x in range(w):
                if pixdata[x, y] < threshold:
                    pixdata[x, y] = 255
                else:
                    pixdata[x, y] = 0
        #取反色
        #img.show()
        pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
        #这里应该是你的ocr程序的安装地址
        result = pytesseract.image_to_string(img)
        #将图片转换为字符串
        resultj = re.sub(u"([^\u4e00-\u9fa5\u0030-\u0039\u0041-\u005a\u0061-\u007a])", "", result)
        #正则表达式,除去特殊字符
        result_four = resultj[0:4]
        print('验证码是'+str(result_four))
        return result_four
    
    #该函数功能是登录
    def login(self):
        print('正在登录中,请稍后')
        n=0
        #下面这是一个循环,因为验证码可能不能一次正确,需要不断尝试
        while True:
            n+=1
            print('第%d次登录中'%n)
            #下面这两个sleep表示暂停1秒,因为网页需要加载,这样更保险
            sleep(1)
            self.driver.refresh()
            #刷新页面,因为上一次循环登录过,刷新重来
            sleep(1)
            self.driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")
            #该js脚本作用是将滚动条滑至顶部
            self.driver.find_element(By.ID, "login_btn").click()
            self.driver.find_element(By.ID, "UserName").send_keys(self.un)
            self.driver.find_element(By.ID, "Password").send_keys(self.pw)
            #输入用户名以及密码
            code=self.processing_pictures()
            self.driver.find_element(By.ID, "codein").send_keys(code)
            self.driver.find_element(By.ID, "sub").click()
            try:
                alert=self.driver.switch_to_alert()
                alert.accept()
            except:
                break
            #如果没有弹出警告窗,也就是登录成功,循环体结束,如果弹出,则accept关闭弹窗
            '''
            其实这个被注释的脚本也可以实现检查是否正常登录
            sleep(1)
            self.driver.refresh()
            sleep(1)
            html = self.driver.page_source
            if html.find('个人中心') == -1:
                break
            '''
            print('第%d次登录失败,正在重试'%n)
        self.driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")
        #作用见上面
        print('登录成功,一共尝试了%d次'%n)
        self.attend_class()

    #该函数功能是上网课
    def attend_class(self):
        print('开始刷课')
        for course in range(int(self.cbe),int(self.cen)+1):
            url='http://hnqmgc.17el.cn/ymzs/zxzr/484770_qmzx.shtml?kcid='+str(course)
            self.driver.get(url)
            # 进入相关课程播放页面
            #sleep(30) 如果播放插件被阻塞,应该预留一点时间再重新打开它
            # coursename=self.driver.find_element_by_id("courseName").text()
            print('当前正在刷id为{0}的课程:'.format(course))
            #下面的部分填坑
            sleep(5)


if __name__ == '__main__':
    print('****************欢迎使用青马网课刷课系统v1.0!*****************')
    print('*             Author:STL_CC  2020.03.18  v1.0               *')
    print('*            Blog:https://blog.csdn.net/STL_CC              *')
    print('*************************************************************')
    print('请输入相关信息:')
    username=input('Username:')
    password=input('Password:')
    cb=input('开始课程id:')
    ce=input('结束课程id:')
    print('开始刷课!')
    a = Class(username,password,cb,ce)
    a.login()

后话

1.以上程序仅实现了登陆功能,具体的刷课进程可见Python刷青马,但是他这个实现方法只是模拟鼠标点击,需要图形化界面,应用场景十分有限。
2.听说JavaScript能控制flash播放器的运行,而且selenium可以使用自定义js脚本,然而笔者没有学过,而且已经开发了快三天,还要上课,吃不消,待有时间学完js后可能会在此填坑,如果哪位大佬懂js,可以一起继续开发
3.课程id就是每个视频最前面那个东东,你也可以观察视频链接
4.由于自动化测试工具的特殊性,可能要针对自己的电脑运行环境进行一些特殊的处理,这个程序我也鼓捣了很久才调好环境,如果由大佬需要技术支持,可以私信笔者。
5.这里是开发的套件包,Firefox 55以上不支持flash自动运行,这是可以支持的版本,请用此套件开发
链接:https://pan.baidu.com/s/1XXHxkd5KXs5rRFyS19yt6A
提取码:q3pp
emmmm 附件里的python程序缺少了几个库,以上面的为准

最近更新:笔者已经对js控制flash控件进行了测试,得要这个控件的属性对外开放才行,所以目前来看只有两种解决的方法,一个是使用autoit或者pyautogui等进行模拟鼠标点击,另一种是我猜的,可以抓包欺骗服务器

与其花这几天时间做这个工程,其实还不如老老实实刷,但是,通过这三天来的不断测试,笔者掌握python复杂编程的能力有了很大提高。也了解了网页的基本结构和selenium工具,以后应对简单的工程,签个到啥的还是很容易上手了的
也希望这个项目的某些方面能给读者以启发

发布了36 篇原创文章 · 获赞 6 · 访问量 4797

猜你喜欢

转载自blog.csdn.net/STL_CC/article/details/104948115