[未优化整理]python3selenium模块操控FireFox火狐浏览器,用于识别验证码登录系统,自动完成观看某网站的系列视频.

一. 需要用到的模块

  from selenium import webdriver  # 用于操控浏览器

  from PIL import Image  # 用于图片截取,修改. 模块安装方法pip install pillow

  import pytesseract  # 用于识别验证码

  import bs4  # 主要用其中的bs4.BeautifulSoup类, 用于分析网页源代码,提取出超链接地址

二. 准备工作

  1. 下载geckodriver,并解压复制到python安装的目录中.此程序是火狐浏览器的驱动程序,有了它python selenium模块才能驱动浏览器做事情.

    下载网址:https://github.com/mozilla/geckodriver/releases

  2. 下载tesseract-ocr,并安装到操作系统中.安装完成后将该软件的安装目录添加到操作系统的环境变量中.一般安装地址是:C:\Program Files (x86)\Tesseract-OCR\,环境变量设置完后一定要重启电脑.

    此软件是谷歌公司的文字识别软件,我们将它配合pytesseract模块,用于识别验证码,

    下载网址:https://digi.bib.uni-mannheim.de/tesseract/

  3. 安装火狐浏览器

三. 程序设计中的关键点:

  1. 程序主要分为两部分,一是登录, 二是学习

  2. 处理弹窗

  3. 使用BeautifulSoup提取出网页上的所有课程地址, 根据网页中的'finished'区分出那些是已经学了的,哪些尚未学的.

  4. 尚却错误处理功能

四. 源代码: 彩色图片优化为黑字白底图片,凸显验证码,更利于后面的文字识别

def ps_img(png_a, png_b):
    """
    彩色图片优化为黑字白底图片,凸显验证码,更利于后面的识别
    :param png_a: 原图片
    :param png_b: 优化后输出图片
    :return: '彩色图片优化为黑白图片完毕,输出文件名为:%s' % png_b
    """
    img = Image.open(png_a)  # from PIL import Image
    imgPs = img.convert('L')
    threshold = 140
    table = []
    for i in range(256):
        if i < threshold:
            table.append(0)
        else:
            table.append(1)
    out = imgPs.point(table, '1')
    out.save(png_b)
    return '彩色图片优化为黑白图片完毕,输出文件名为:%s' % png_b
验证码图片优化为黑字白底

五. 源代码: 图片识别输出为文字

def png_to_str(png='imgCodePs.png'):
    """
    图片识别为文字
    :param png: 图片文件名
    :return: 字符串
    """
    imgCode = Image.open(png)  # from PIL import Image
    time.sleep(0.5)
    strCode = pytesseract.image_to_string(imgCode)  # import pytesseract
    return strCode
图片识别并输出为文字

六. 完整未优化的源代码

# -*- coding: utf-8 -*-
# programming environment:windows7_64 + python3.8.3_64

from selenium import webdriver
from PIL import Image
import pytesseract, time
import bs4


def ps_img(png_a, png_b):
    """
    彩色图片优化为黑字白底图片,凸显验证码,更利于后面的识别
    :param png_a: 原图片
    :param png_b: 优化后输出图片
    :return: '彩色图片优化为黑白图片完毕,输出文件名为:%s' % png_b
    """
    img = Image.open(png_a)  # from PIL import Image
    imgPs = img.convert('L')
    threshold = 140
    table = []
    for i in range(256):
        if i < threshold:
            table.append(0)
        else:
            table.append(1)
    out = imgPs.point(table, '1')
    out.save(png_b)
    return '彩色图片优化为黑白图片完毕,输出文件名为:%s' % png_b


def png_to_str(png='imgCodePs.png'):
    """
    图片识别并输出为文字
    :param png: 图片文件名
    :return: 字符串
    """
    imgCode = Image.open(png)  # from PIL import Image
    time.sleep(0.5)
    strCode = pytesseract.image_to_string(imgCode)  # import pytesseract
    return strCode


if __name__ == '__main__':
    print('江苏教师教育学习开始,先登录....')
    url_index = 'https://www.jste.net.cn/uids/'
    account = {'name': '*****', 'pwd': "********"}  # 需要登录的账户
    browser = webdriver.Firefox()  # 驱动火狐浏览器
    browser.get(url_index)  # 打开指定的网页
    time.sleep(2)

    # 用户登录环节
    # 点击验证码输入框,让验证码显示或变换
    browser.find_element_by_name("randomCode").click()  # 找到验证码输入框
    while True:
        """
        用户登录环节
        """
        time.sleep(2)
        # 1. 获取验证码图片
        # 1.1 获取验证码图片的左上角位置值和右下角的位置
        imgCode = browser.find_element_by_id('imgCode')
        imgCodeXY = imgCode.location  # 验证码图片的左上角坐标值
        imgCodeSize = imgCode.size  # 验证码的长宽值
        imgCodeLocation = (int(imgCodeXY['x']), int(imgCodeXY['y']), int(imgCodeXY['x']) + int(imgCodeSize['width']),
                           int(imgCodeXY['y']) + int(imgCodeSize['height']))  # 验证码左上右下位置值
        # 1.2 截图验证码图片,保存为图片
        time.sleep(0.5)
        browser.save_screenshot('login.png')
        # print(imgCodeLocation)
        time.sleep(0.5)
        loginImg = Image.open('login.png')
        time.sleep(0.2)
        imgCodeImg = loginImg.crop(imgCodeLocation)
        time.sleep(0.2)
        imgCodeImg.save('imgCode.png')
        time.sleep(0.2)

        # 2. 识别验证码
        # 2.1 图片优化
        ps_img('imgCode.png', 'imgCodePs.png')
        time.sleep(0.2)
        # 2.2 图片识别为文字
        strCode = png_to_str('imgCodePs.png')
        time.sleep(0.1)
        # print(len(strCode))
        # print(strCode.isalpha())
        # 2.3 清理识别的错误字符串,验证码必须为字母,其余的舍弃.
        strCodeList = []
        for i in strCode:
            if i.isalpha() is True:
                strCodeList.append(i)
        strCode = ''.join(strCodeList)
        print(strCode, len(strCode), strCode.isalpha())
        # 2.4 字母必须是5位
        if len(strCode) != 5:
            print('验证码识别有误,将重新获取验证码,再进行识别!')
            # 点击验证码图片,变换验证码
            browser.find_element_by_id('pwd').click()
            browser.find_element_by_id('randomCode').click()
            time.sleep(1)
            continue
        # 3. 登录验证
        # 3.1 输入验证码
        randomCode = browser.find_element_by_name('randomCode').send_keys(strCode)
        time.sleep(0.5)
        # 3.2 输入用户名密码
        browser.find_element_by_name('loginName').send_keys(account['name'])
        time.sleep(0.1)
        browser.find_element_by_name('pwd').send_keys(account['pwd'])
        time.sleep(0.1)
        # 3.3 点击登录
        browser.find_element_by_class_name('Button').click()
        time.sleep(2)
        # 3.4 判断登录是否成功
        url_ok = 'https://www.jste.net.cn/train/credit_hour/index.jsp'
        if browser.current_url == url_ok:
            print('登录成功')
            break
        else:
            print('登录失败,重新尝试...')


    # 学习环节
    print('进入学习环节')
    time.sleep(2)
    # 用户个人首页
    browser.switch_to.frame('mainFrame')  # 切换到页面中的第二个框架
    study_list = []  # 存储用户需要学习的课程网址
    url_front = 'https://www.jste.net.cn/lfv5/learnContentLib/studentMain.action'  # 课程网址的前半部分
    # 点击进入学习,弹出"已经为您自动跳转到上次学习的章节"
    browser.find_element_by_link_text('开始学习').click()  # 点击"开始学习"进入根目录
    time.sleep(5)
    # 处理弹出窗口
    first_handle = browser.current_window_handle
    handles = browser.window_handles
    for i in handles:
        if i != first_handle:
            print('处理我要从头学习弹窗')
            browser.close()  # 关闭当前窗口
            browser.switch_to.window(i)  # 切换到弹出窗口
            browser.find_element_by_link_text('我要从头学习').click()  # 进入根目录

    time.sleep(2)
    while True:
        time.sleep(1)
        html = browser.page_source  # 获取当前页面的html网页源代码
        soup = bs4.BeautifulSoup(html, 'html.parser')
        courseAllHtml = soup.select('.item')  # 筛选html,获取所有课程的html代码
        for courseHtml in courseAllHtml:
            if 'finished' not in str(courseHtml):  # 获取未完成的课程html的str类型,并检查是否包含完成标志.
                study_list.append(courseHtml.get('href'))  # 将未完成的课程链接加入到列表中

        # 遍历课程
        for link in study_list:
            browser.get(url_front + link)  # 打开课程页面
            print('打开课程页面')
            time.sleep(1)
            browser.find_elements_by_class_name('left0')[0].click()  # 点击打开2.视频资源
            print('打开2.视频资源页面')
            time.sleep(5)
            html = browser.page_source  # 获取当前页面的html网页源代码
            soup = bs4.BeautifulSoup(html, 'html.parser')
            videoAllHtml = soup.select('.item')  # 筛选html,获取所有视频链接的html代码<a>标签
            time.sleep(0.1)
            # 遍历课程下的视频
            for videoHtml in videoAllHtml:
                print(str(videoHtml))
                if 'finished' not in str(videoHtml):
                    videoHtml.get('href')
                    browser.get(url_front + videoHtml.get('href'))
                    print('打开视频播放页面')
                    time.sleep(60)
                    while True:
                        time.sleep(10)
                        html = browser.page_source  # 获取当前页面的html网页源代码
                        if '本项学习时间已满' in str(html):  # 检查视频播放页面中是否有 本项学习时间已满 文字提示
                            print('单个视频观看结束')  # 单个视频观看结束
                            browser.find_element_by_class_name('back').click()  # 点击右上角返回按钮
                            print('点击返回上级,返回2.视频资源页面')
                            time.sleep(2)
                            break
                        else:
                            print('当前视频尚未播放结束')
未优化的完成源代码

 七. 谷歌浏览器各版本驱动下载:

  http://npm.taobao.org/mirrors/chromedriver/

posted @ 2021-01-23 16:51  蓝蓝的白云天!  阅读(396)  评论(0编辑  收藏  举报