CC的小站

  • 首页
  • 友链
  • 小游戏
  • 关于 / 留言板

使用selenium自动化播课

发表于 2022-05-30 |

警告:使用脚本刷课是不对的,好孩子不要这样做。

正好前些日子课上让学网络爬虫,就了解到了selenium————一个能实现网页自动化的库,Java、Py都能使。正好想到学习通上那无聊的网络选修课还不少没看,就准备来实操一下练练手。

我之前没发现java也行,就去py里搞了,还专门下了个PyCharm(JB家的东西真不错)。我这里配置库靠IDE,打完“import selenium”后就提示我自动安装了,浏览器引擎使得是Edge,去官网下就行。

程序:

import random
import sys
import time

from selenium import webdriver

# Powered By CC2001
# 学习通网课自动看视频,默认为每节课的第一个项目就是视频,如果不是可以自行修改“learn”函数

phone = ''  # 填入学习通手机号
password = ''  # 填入学习通密码
headLess = True  # 无头模式(不显示渲染浏览器),有头还是更稳定一些


def changeToIframeByX(xpath):
    iframe = driver.find_element_by_xpath(xpath)
    driver.switch_to.frame(iframe)  # 切换到iframe


def changeToIframeByID(frameID):
    iframe = driver.find_elements_by_id(frameID)
    driver.switch_to.frame(iframe[-1])  # 切换到iframe


def sleep():
    time.sleep(round(random.random(), 1) + 0.5)


def timeToS(timeStr):
    t = timeStr.strip().split(':')
    if len(t) == 2:
        mm, ss = t
        return int(mm) * 60 + int(ss)
    elif len(t) == 3:
        hh, mm, ss = t
        return int(hh) * 3600 + int(mm) * 60 + int(ss)


def getTime():
    return time.strftime('[%H:%M:%S]', time.localtime())


if headLess:
    EDGE = {
        "browserName": "MicrosoftEdge",
        "version": "",
        "platform": "WINDOWS",
        "ms:edgeOptions": {
            'extensions': [],
            'args': [
                '--headless',
            ]}
    }
else:
    EDGE = None

driver = webdriver.Edge(executable_path='msedgedriver.exe', capabilities=EDGE)  # executable_path为下载的Edge引擎的路径
driver.set_window_rect(-1000, -1000, 1000, 1000)
driver.implicitly_wait(5)
driver.get('https://passport2.chaoxing.com/login?fid=&newversion=true')  # 学习通登录界面

if phone == '':
    phone = input("学习通绑定的手机号:")
driver.find_element_by_id('phone').send_keys(phone)

if password == '':
    password = input("学习通密码:")
driver.find_element_by_id('pwd').send_keys(password)

sleep()
driver.find_element_by_id('loginBtn').click()

changeToIframeByX('/html/body/div[2]/div[2]/iframe')

subjects = driver.find_element_by_xpath(
    '/html/body/div[1]/div/div/div[2]/div/div[2]/div[2]/ul').find_elements_by_tag_name('li')

notNullSubjects = []
for s in subjects:
    if s.text != "":
        notNullSubjects.append(s)

for index, s in enumerate(notNullSubjects):
    print("[%d]:" % index, s.text.replace("\n", " "))
print("---------------------------------------------------")

inp = input("输入科目序号:")
try:
    inp = int(inp)
except ValueError:
    print("格式错误,即将退出")
    driver.quit()
    sys.exit()
else:
    notNullSubjects[inp].find_element_by_tag_name('a').click()
    notNullSubjects.clear()

handles = driver.window_handles  # 获取当前全部窗口句柄集合
for handle in handles:  # 切换窗口
    if handle != driver.current_window_handle:
        driver.close()  # 关闭第一个窗口
        driver.switch_to.window(handle)  # 切换到第二个窗口
driver.minimize_window()
driver.find_element_by_xpath('/html/body/div[1]/div[3]/div[1]/div/ul[1]/li[2]/a').click()

sleep()
changeToIframeByID('frame_content-zj')
classes = []
for x in driver.find_elements_by_xpath('/html/body/div[1]/div/div[2]/div[2]'):
    for index, xx in enumerate(x.find_elements_by_tag_name('li')):
        classes.append(xx)
        print("[%d]:" % index, xx.text.replace("\n", " 任务数:"))
classes.clear()
driver.switch_to.parent_frame()
print("---------------------------------------------------")


def learn(o):
    global driver
    sleep()
    changeToIframeByID('frame_content-zj')
    for c in driver.find_elements_by_xpath('/html/body/div[1]/div/div[2]/div[2]'):
        for index1, cc in enumerate(c.find_elements_by_tag_name('li')):
            if index1 == o:
                cc.click()
    sleep()
    driver.set_window_rect(-1000, -1000, 1000, 1000)
    changeToIframeByX('/html/body/div[4]/div/div[3]/div[5]/iframe')
    changeToIframeByX('/html/body/div/div/p[1]/div/iframe')
    driver.find_element_by_tag_name('button').click()
    sleep()
    print('%s正在播放编号为“%d”的课程' % (getTime(), o), end=': ')
    time.sleep(needTime() + 3)
    print('%s编号为“%d”的课程已播放完毕' % (getTime(), o))
    driver.switch_to.parent_frame()
    driver.switch_to.parent_frame()
    driver.find_element_by_xpath('/html/body/div[4]/div/div[1]/a').click()
    sleep()


def needTime():
    try:
        sleep()
        timeNow = driver.find_element_by_xpath('/html/body/div/div[4]/div/div[5]/div[2]/span[2]').text
        timeStop = driver.find_element_by_xpath('/html/body/div/div[4]/div/div[5]/div[4]/span[2]').text
        n = timeToS(timeStop) - timeToS(timeNow)
    except TypeError:
        print('进度获取失败,准备退出当前课程')
        return 1
    else:
        if n > 0:
            print('%s/%s,需要%d秒' % (timeNow, timeStop, n))
        driver.minimize_window()
        return n


print("可输入一个编号,或输入两个中间夹着“:”的编号(“a:b”代表[a,b])。输入其他格式可退出程序。")
inp = input("输入课程序号:")
if ":" in inp:
    inp = inp.split(":")
else:
    inp = inp.split(":")
if len(inp) == 1:
    try:
        s = int(inp[0])
    except ValueError:
        print("无法识别,即将退出")
    else:
        learn(s)

elif len(inp) == 2:
    s, e = inp
    try:
        s = int(s)
        e = int(e)
    except ValueError:
        print("无法识别,即将退出")
    else:
        if s > e:
            temp = s
            s = e
            e = temp
        for i in range(s, e + 1):
            learn(i)
        print("%s%d到%d所有课程播放完毕" % (getTime(), s, e))

driver.quit()

其他:

我没使过太久Python,写的可能有点怪,但还是差不多能跑的。逻辑上很简单,就是和脚本一样,得照着网页提前把处理方式录入好。善用“F12”,编起来没啥难度。需要使用的元素在iframe里的需要先切进去,切进去后的环境就是新的网页,用外面的东西时记得切出来。

科技改变生活😍

Floo_Powder

发表于 2022-05-18 |

2022/5/26已更新:1.3版本

飞路粉模组

B站上的部分介绍:https://www.bilibili.com/video/BV1Lr4y1b7UQ
Github上的源码及jar包:https://github.com/C20C01/Floo_Powder

简介:

  • 版本:JE1.18.2 Forge
  • 内容:通过飞路粉进行定点传送

具体内容:

东西不多一共就5样:飞路粉、传送火焰、传送火石、传送核心、传送核心大全。
1.3版本新增:飞路粉分发器

  • 飞路粉(Floo powder)
    火药 + 绿宝石合成。将其丢入任意竖直火焰就能将火焰及其所有相连的火焰转变成传送火焰(绿色火焰)。
    被竖直火焰之外的火焰伤害(被岩浆烧掉、被在侧面燃烧的火焰烧掉等等)烧毁会产生极小的爆炸(没有伤害仅作提示)。

  • 传送火焰(PortalFireBlock)
    由飞路粉生成,飞路粉的命名决定了传送火焰的标签。
    任意生物进入传送火焰后就会尝试传送到与火焰拥有相同标签的传送核心上方:

    • 若有相同标签的传送核心:
      生物会传送过去(理论上支持任意维度)且会被赋予一段时间的火焰免疫,同时传送火焰及其相连接的所有拥有相同标签的传送火焰会被熄灭。

    • 若无相同标签的传送核心:
      会尝试传送到名为 UNKNOWN 的传送核心,若没有则熄灭火焰并进行文本提示和音效提示。

    • 若有相同标签的传送核心但其尚未被加载:
      熄灭火焰并进行文本提示和音效提示。

  • 传送火石(Teleport Flint and Steel)
    水晶碎片 + 青金石合成。
    一次性用品,在传送核心顶部使用可激活并将核心的标签设置为传送火石的命名。

  • 传送核心(Teleportation core)
    飞路粉 + 传送火石 + 黑曜石 + 下界合金锭合成。
    激活状态下的核心作为传送火焰通向的终点。仅能被传送火石激活。激活后其顶部的火焰一直会尝试燃烧,在火焰被有碰撞的方块阻挡后便会失去激活状态。在有重复的标签的情况下,先前的传送点作废但核心仍会在激活状态(仅能继续不断点火)。激活状态下对核心点击使用键可查看核心的标签。

  • 传送核心大全(Book of Teleportation cores)
    无法合成,仅能通过创造模式或指令获得。手持传送核心大全点击使用键即可在聊天栏获取世界所有维度的所有已激活的传送核心的信息。*1.3版本新增:可手持传送核心大全对飞路粉分发器点击使用键即可进入编辑模式。

  • 飞路粉分发器(Powder giver)
    无法合成,仅能通过创造模式或指令获得。使用可打开GUI,可以看到所有已激活的传送核心的名字和描述,并可选择一个传送点获得对应的飞路粉。
    使用传送核心大全可进入编辑模式,对指定的传送点的描述进行编辑。

举例说明:

你现在有传送核心1 传送火石1 打火石*1 飞路粉若干。若要激活核心并可使用飞路粉进行传送你需要:

  1. 使用铁砧将传送火石、飞路粉均命名为 WDNMD(仅作示例,起啥名随你,也可以用汉字)
  2. 在你想要设立传送点的地方放置传送核心,需保证核心上方一格为空气(传送时会传到那里)。
  3. 使用命名完的传送火石对传送核心顶部使用。如果一切正确,此时核心上方会着火,并有信标激活的音效产生。
  4. 使用打火石或其他手段在方块顶部点火,并将命名完的飞路粉丢入其中。
  5. 走进传送火焰。如果没有问题此时你就会被传送到你刚刚所激活的传送核心上方。

杂谈:

离上次更新博客也过去差不多半个月的时间了,期间蓝桥杯省赛得了一等奖,6月多就该试试国赛了,名单看下来搞Java的人好少啊。反正我是很喜欢Java的。
派克惨遭削弱,核心的钱袋袋不行了,就硬往辅助位压。再加上打得菜、心态也不行被喷退游了。这东西老不碰也就忘了到底怎么好玩了,也就没多大兴趣了,但打起来是真的上瘾。
这一阵子北京又开始闹起疫情来了,连续一两周了天天都在做核酸,不知道会对今年北京的中高考会有啥影响,反正对各行各业的负面影响都挺大的。

从去年的TeaCon参观了一下、在QQ群里潜许久的水,就也想参加一下试试(水个钥匙坠 嘻嘻)。记得去年第一次参与这种活动,虽然只是一个观众,但这种氛围还是让人向往的,与来自五湖四海的陌生人在同一个服务器上不断探索新鲜事物,与众多的模组作者分享他们的快乐。这次能以参赛者再参加一下也算是一个很好美好的回忆吧。

本届的主题是“火”,想了想就准备做一个自己觉得相对简单一些的火焰传送(飞路粉)也不知道是怎么想起来的,可能是因为头顶就放着一套《哈利波特》吧(bushi)。想着挺简单的但做起来还是很费劲的,主要是对服务端与客户端分不太清楚,对游戏内部机制还是不太了解。好在GitHub上有传送模组(WatStone),再加上boson的教程(虽然是1.16的,但还是很有参考价值的),天天熬,终于用一礼拜的时间做出了模组的雏形。虽然部分原理并不太清楚,但是能跑就行了 hhh。

大表哥2通关了

发表于 2022-05-04 |

好久之前趁Epic打折买的算上优惠券,好像40多入的手。断断续续一直打,剧情挺好的,快结束时挺感动的,买得挺值。挺不错。

<--1…678…32-->

CC2001

94 日志
GitHub BiliBili
© 2025 CC2001
由 Hexo 强力驱动
|
主题 — NexT.Pisces