欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于python+webdriver实现杭电正方系统的自动化抢课程序

程序员文章站 2023-01-25 16:39:01
废话不多说,上程序代码import requestsfrom selenium import webdriverfrom selenium.webdriver import ChromeOptionsimport parselimport timefrom selenium.webdriver.common.action_chains import ActionChainsfrom selenium.webdriver.common.by import Byimport jsonimp...

先看一下正方教务系统的主页面
基于python+webdriver实现杭电正方系统的自动化抢课程序
俺们杭电人废话不多说,直接上程序
代码

import requests
from selenium import webdriver
from selenium.webdriver import ChromeOptions
import parsel
import time

from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import json
import requests
import base64
from io import BytesIO
from PIL import Image
from sys import version_info
import threading
url = 'http://jxgl.hdu.edu.cn/default.aspx'
headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.9 Safari/537.36'}
def main():

    # askurl(url)
    # getnlink(url)
    getdata()
def dri(url):   #登陆页面
    option = ChromeOptions()  # 添加用户配置
    option.add_experimental_option('excludeSwitches', ['enable-automation'])  # 模拟开发者模式
    driver = webdriver.Chrome(options = option)
    driver.get(url)
    driver.find_element_by_id('un').clear()  # 清空输入框
    driver.find_element_by_id('un').send_keys('18081828')  # 输入学号
    driver.find_element_by_id('pd').clear()
    driver.find_element_by_id('pd').send_keys('Hdu1041116')  # 输入密码
    driver.find_element_by_id('index_login_btn').click()
    return driver

def action():

    driver = dri(url)
    # html = driver.page_source
    # data = parsel.Selector(html)
    # ylink = data.xpath('//img[@src]').extract[0]
    # print(ylink)
    ActionChains(driver).move_to_element(driver.find_element_by_link_text("网上选课")).perform()
    time.sleep(1)
    driver.find_element_by_link_text(class_nature).click()
    driver.switch_to_default_content()
    frame = driver.find_elements_by_tag_name('iframe')[0]
    driver.switch_to_frame(frame)
    time.sleep(1)
    # time.sleep(2)
    # ActionChains(driver).click(driver.find_element_by_id("ddl_ywyl")).perform() #有无余量
    # # time.sleep(1)
    # driver.find_element_by_xpath('//option[@value="有"]').click()

    ActionChains(driver).click(driver.find_element_by_id("ddl_kcgs")).perform()#课程性质
    driver.find_element_by_xpath('//option[@value="通识选修一般课"]').click()
    # ActionChains(driver).click(driver.find_element_by_id("ddl_sksj")).perform() #上课时间
    # driver.find_element_by_xpath('//option[@value="周二第10,11节{第1-16周}"]').click()
    driver.find_element_by_id('TextBox1').send_keys(class_name)  #课程名
    driver.find_element_by_id('Button2').click()
    driver.find_element_by_id('kcmcGrid_ctl02_xk').click()  #选择课程
    time.sleep(1)
    driver.find_element(By.XPATH,'//img')
    driver.save_screenshot("yzm2.png")
    ran = Image.open("yzm2.png")
    box = (1125, 485, 1190, 525)  # 获取验证码位置,自动定位不是很明白,就使用了手动定位,代表(左,上,右,下)
    ran.crop(box).save("yzm3.png")
    img_path = "yzm3.png"
    img = Image.open(img_path)
    result = base64_api(uname='shj', pwd='shj459321', img=img)
    driver.find_element_by_id('txtYz').clear()
    driver.find_element_by_id('txtYz').send_keys(result)
    driver.find_element_by_id('Button1').click()

def getdata():
    for i in range(0,5):
        t = threading.Thread(target=action, name="" + str(i), args=())
        t.start()

def base64_api(uname, pwd, img):	#调用第三方网站的api
    img = img.convert('RGB')
    buffered = BytesIO()
    img.save(buffered, format="JPEG")
    if version_info.major >= 3:
        b64 = str(base64.b64encode(buffered.getvalue()), encoding='utf-8')
    else:
        b64 = str(base64.b64encode(buffered.getvalue()))
    data = {"username": uname, "password": pwd, "image": b64}
    result = json.loads(requests.post("http://api.ttshitu.com/base64", json=data).text)
    if result['success']:
        return result["data"]["result"]
    else:
        return result["message"]
    return ""

def main1():
    img_path = "yzm.jpg"
    img = Image.open(img_path)
    result = base64_api(uname='shj', pwd='shj459321', img=img)
    return result


if __name__ == '__main__':
    class_nature = '通识选修课'
    class_name = '澳大利亚的文化之旅'
    main()

if name == ‘main’:
class_nature = ‘通识选修课’
class_name = ‘澳大利亚的文化之旅’
main()

``
解释:代码其实很简单,无非就是selenium控制鼠标键盘和webdriver定位元素的一些操作,详情可以(https://blog.csdn.net/qq_32897143/article/details/80383502),要是还有不懂得可以找度娘,度娘是万能的
比较棘手的就是验证码识别的问题,本人以前也自学过机关于python机器学习人工智能方面的一些知识,但是验证码识别到现在都有没成功实现过,所以我就找了一个第三方打码平台(http://www.ttshitu.com/user/index.html)

基于python+webdriver实现杭电正方系统的自动化抢课程序
资费很便宜,我充了一块钱到现在都没有花完,而且识别率也很高,很方便,适合小白入手
但还是很建议大家取试试自己写模型,嘿嘿嘿,学会了可以教教我哦!
还有一个困扰了我好久的问题,就是验证码图片的获取
基于python+webdriver实现杭电正方系统的自动化抢课程序
大家可以看,验证码图片在网页中是有展示了,那应该很好获取呀,直接获取验证码图片url然后下载识别不就行了,嘿嘿,其实不然,你点开他的源码,发现
基于python+webdriver实现杭电正方系统的自动化抢课程序
它的url并不能直接访问验证码图片地址,而且.aspx图片格式是随机生成的,你捕捉的验证码图片跟原来的验证码图片肯定不一致(访问一次刷新一次嘛),所以,我就使用了另一种方法,大家请看:

driver.save_screenshot("yzm.png")
ran = Image.open("yzm.png")
box = (1120, 630, 1180, 670)  # 获取验证码位置,自动定位不是很明白,就使用了手动定位,代表(左,上,右,下)
ran.crop(box).save("yzm1.png")
img_path = "yzm1.png"
img = Image.open(img_path)

就是用save_screenshot函数将整个屏幕截图下来,再手动定位到验证码位置,生成一张新的验证码图片,当然,这种方法非常的片面,因为每个课程验证码的位置都是不同的,所以要具体课程具体定位咯
好了,本次的分享就到此结束啦,希望大家多多支持小编呀

本文地址:https://blog.csdn.net/lingling186/article/details/107545577

相关标签: 抢课脚本