分享

教你用Python实现全自动刷网课

 wenxuefeng360 2022-07-03 发布于四川

赛季末,如何实现自动刷掉毫无意义的网课?

演示

(双枪) 双手会给出答案
在这里插入图片描述

不妨自己动手用Python试一试。只想看源代码的可以直接滑到文章的最底部。

阅读前你可能需要:

1. Python基础 / 相关编程基础

2. HTML 等前端方面的相关知识

3. 浏览器 (本人使用的是Chrome)

4. 浏览器对应版本的Driver

5. Python中安装好Selenium库

6. 还没刷完 且 毫无意义的网课

一、原理介绍

Python中有个名为Selenium的库,是一种知名的自动化测试库,利用它,可以实现浏览器中的点击、输入等操作,从而实现自动化刷课(或者其他合法的事情)

所以只要分析网页的源代码,就可以实现自动化操作网页。

在模拟操作的过程中,必须提前知道即将发生什么,才能完美的自动化测试。

二、准备工作

1)安装Python3 (反正安装最新版本)

官网搜索就行

在这里插入图片描述

(安装完后在终端自查:输入python,如图则安装完成)

2)安装Chrome & ChromeDriver

浏览器就不多说了,这里给出Driver的地址

chromedriver.storage.googleapis.com/index.html

在这里插入图片描述

(python安装目录script中放入对应版本的driver)

3)在Python中安装Selenium库

安装前其实要先安装pip,默认安装是有勾选的,而且这里网上有很多方法了,不多赘述。

安装好pip后可以在终端命令行中输入

pip install selenium

在这里插入图片描述

(安装selenium中)

在这里插入图片描述

(自查安装是否完成:pip show selenium)

4)编辑环境

在系统中把python的目录添加进去就行,网络上也有很多,不多赘述。

三、实现

(一)自动打开并且登陆网站

选择你要那啥的平台,这里使用mooc作为演示

获取它的URL

在这里插入图片描述

#引用库
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
​
#全局变量区域
url = "https://www.icourse163.org/"
driver = webdriver.Chrome()
​
​
#打开网页  最好全屏
driver.get(url)
driver.maximize_window()

运行代码就可以看见浏览器自动打开并且进入了mooc

但是由于自动化测试软件打开的浏览器没有cookie,不会识别用户

所以需要设计一下自动登陆的部分

(二)实现自动登陆

在浏览器中按F12 打开调试台 再点击这个按钮

在这里插入图片描述

这个是元素选择器,选择那个绿色的“登陆/注册”

之后会跳出对应的

标签,复制它的FULL XPath

(确定元素位置有很多种方式,xpath是相对准确的一种,确定元素位置相当于告诉电脑你该在哪里进行操作)

在这里插入图片描述

(演示,gif中复制的是xpath,应该复制full xpath)

自己点击后可以发现,出来默认是扫码登陆,我们选择其他方式登陆,这里用邮箱演示。

可以声明一下变量(#在python中是注释符)

#全局变量区域
url = "https://www.icourse163.org/"
driver = webdriver.Chrome()
account = '***@163.com' #改成自己的账户
password = '**********' #改成自己的密码

刚刚复制的xpath在这里 (这里其实复制的是full xpath,mooc对xpath有随机数的id,每次打开都不一样,所以用full xpath)

/html/body/div[4]/div[2]/div[1]/div/div/div[1]/div[3]/div[3]/div

重复上述操作找到各个按钮的xpath,在代码中添加几个点击的动作

为了方便调试,大多数操作采用try-expcet语句

(但是前期敲代码的时候,建议先不要用try-except语句,因为编译器报错的信息更有用)

mooc网点击登陆后,会弹出新的小页面,由于weddriver每次只能识别一个页面,这里直接.switch_to_frame()

在这里插入图片描述

#登陆部分
try:
    driver.find_element(By.XPATH, '/html/body/div[4]/div[2]/div[1]/div/div/div[1]/div[3]/div[3]/div').click()
    driver.find_element(By.XPATH, '/html/body/div[13]/div[2]/div/div/div/div/div[2]/span').click()
    print('点击登陆按钮成功\n')
except:
    print('点击登陆按钮时出错')
​
​
#输入账号密码部分
try:
    driver._switch_to.frame(0) #这里转到fame0 因为mooc网站点击登陆后是弹窗的
    driver.find_element(By.XPATH, '/html/body/div[2]/div[2]/div[2]/form/div/div[1]/div[2]/input').send_keys(account)
    driver.find_element(By.XPATH, '/html/body/div[2]/div[2]/div[2]/form/div/div[3]/div[2]/input[2]').send_keys(password)
    print('输入账号密码成功\n')
    driver.find_element(By.XPATH, '/html/body/div[2]/div[2]/div[2]/form/div/div[8]/a').click()
except:
    print('登陆失败')

上述代码中,总体来说,为了便于理解,是这样一个伪代码

driver.查找元素的方法('元素的位置').操作()
find_element(By.XPATH,'xpath的内容')就是通过xpath来确定元素位置
.click()就是点击的操作, .send_keys(参数)就是输入的操作

这一步完成后应该是这样的效果(登陆次数非常多的时候,可能会有滑动验证)

在这里插入图片描述

(三)选择课程

如果上述操作都能够掌握,后面的其实就只是重复步骤而已,教程其实可以到这里就结束了。

如果还想继续看,请往下滑。

接下来是点击头像进入课程界面,选择课程。

注意:这时候webdriver聚焦在刚刚的frame上,先改回主页面,然后点击头像就可以进入“我的课程”界面

try:
    driver.switch_to.default_content()
    driver.find_element(By.XPATH,'/html/body/div[4]/div[2]/div[1]/div/div/div[1]/div[3]/div[1]/img').click()
    print("点击头像成功\n")
except:
    print("点击头像出错")

接下来这里用 “高等数学(一)” 作为演示

在这里插入图片描述

继续获取元素的XPATH,重复操作即可

 time.sleep(2)
#点击 高等数学(一) 课程
try:
    driver.find_element(By.XPATH,'/html/body/div[4]/div[2]/div[3]/div/div[1]/div[3]/div/div[2]/div/div/div[2]/div[1]/div[2]/div/div[1]/div[1]/div[1]/a/div[1]/img').click()
    print("点击 '高等数学(一)'成功")
except:
    print("点击课程失败")
time.sleep(4)
#点击继续学习
try:
    driver.switch_to.window(driver.window_handles[-1])
    driver.find_element(By.XPATH,'/html/body/div[4]/div[2]/div[4]/div[2]/div/div[1]/div/div[1]/div/div[1]/div/a[1]').click()
    print('点击继续学习成功')
except:
    print("点击继续学习失败")

由于mooc网有自动播放功能,但是没有自动看课件的功能,这里演示观看每节课的课件

PS:其他网课网站(智慧树)有一些是没有自动播放的,非常反人类,这时候就可以运用上面的方法实现自动播放。

分析网页源代码发现,一套课程分为chapter和lesson俩个部分

在这里插入图片描述

(红蓝箭头一一对应)

在lesson的每一节中都有下面的几个

  • 标签

在这里插入图片描述

分析这一行格子的源代码可以发现

在这里插入图片描述

在当前的界面中,li标签中的class属性中多了个current

然后各个li标签的full xpath是有一定规律的

在这里插入图片描述

(可以看见后缀是递增的)

上面说了,这里只演示全部看完课件,核心方法掌握了,就可以触类旁通了。

后来发现,classname似乎锁定不到这个元素,只能暴力破解了。(有好方法的请联系我)

一行最多不过10个格子

在这里插入图片描述

归纳出来是这样的

/html/body/div[4]/div[2]/...(省略)/ul/li[数字]

所以可以通过只改变后面[数字]就行,每次都点击一下,先在全局变量中利用列表存储一下’[数字]’。

#全局变量区域
lists=['1','2','3','4','5','6','7','8','9','10',]

用for循环遍历列表(其实这里已经可以实现自动播放了,只要设置好第二个tiem.sleep()的参数就行)

for i in lists:
  time.sleep(2)
  driver.find_element(By.XPATH,'/html/body/div[4]/div[2]/div[4]/div[2]/div/div[1]/div/div/div[3]/ul/li['+ i +']' ).click()
  time.sleep(2)

这里完成后是这样的。

在这里插入图片描述

(鼠标没有移动)

(四)选择章节和讲数

但是我需要多次点击,而且每次点击都是不同的页面,这时候就不得不分析chapter和lesson的源码

在这里插入图片描述

经过分析发现,俩者的源码也有一定规律

chapters
​
/html/body/div[4]/div[2]/div[4]/div[2]/div/div[1]/div/div/div[1]/div[1]/div/div[1]/div/div[2]/div[章节数]
​
lessons  
​
/html/body/div[4]/div[2]/div[4]/div[2]/div/div[1]/div/div/div[1]/div[1]/div/div[2]/div/div[2]/div[讲数]

注意,这里俩个栏的元素是隐藏的。

在这里插入图片描述

可以通过js来先显示它

js="document.getElementsByClassName('down f-bg j-list')[0].style.display='block'"
driver.execute_script(js)

回到python编辑器,可以打上这样的代码(三个for嵌套)

#全局变量区域
cha='/html/body/div[4]/div[2]/div[4]/div[2]/div/div[1]/div/div/div[1]/div[1]/div/div[1]/div/div[2]/div'
chapters=['1','2','3','4','5','6','7','8','9','10','11','12','13','14']
​
les='/html/body/div[4]/div[2]/div[4]/div[2]/div/div[1]/div/div/div[1]/div[1]/div/div[2]/div/div[2]/div'
lessons=['1','2','3','4','5','6',]
​
#疯狂点击
#点击chapter后点击lesson 然后点击视频和文档
for c in chapters:
    time.sleep(1)
    
    js="document.getElementsByClassName('down f-bg j-list')[0].style.display='block'"
    driver.execute_script(js)
    driver.find_element(By.XPATH,cha+'['+c+']').click()
    
    time.sleep(1)
    for l in lessons:
        try:
            time.sleep(1)
            js2="document.getElementsByClassName('down f-bg j-list')[1].style.display='block'"
            driver.execute_script(js2)
            driver.find_element(By.XPATH,les+'['+l+']').click()
            time.sleep(1)
        except:
            break
        for i in lists:
            try:
                time.sleep(1)
                driver.find_element(By.XPATH,'/html/body/div[4]/div[2]/div[4]/div[2]/div/div[1]/div/div/div[3]/ul/li['+ i +']' ).click()
                time.sleep(1)
            except:
                break

大功告成。

在这里插入图片描述

(实现了不同章节不同讲的切换)

前后进度对比

在这里插入图片描述

四、源代码

#引用库
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
​
​
#全局变量区域
url = "https://www.icourse163.org/"
driver = webdriver.Chrome()
account = '********@163.com'
password = '********'
​
lists=['1','2','3','4','5','6','7','8','9','10',]
​
cha='/html/body/div[4]/div[2]/div[4]/div[2]/div/div[1]/div/div/div[1]/div[1]/div/div[1]/div/div[2]/div'
chapters=['1','2','3','4','5','6','7','8','9','10','11','12','13','14']
​
les='/html/body/div[4]/div[2]/div[4]/div[2]/div/div[1]/div/div/div[1]/div[1]/div/div[2]/div/div[2]/div'
lessons=['1','2','3','4','5','6',]
​
#打开网页
driver.get(url)
driver.maximize_window()
​
#登陆部分
try:
    driver.find_element(By.XPATH, '/html/body/div[4]/div[2]/div[1]/div/div/div[1]/div[3]/div[3]/div').click()
    driver.find_element(By.XPATH, '/html/body/div[13]/div[2]/div/div/div/div/div[2]/span').click()
    print('点击登陆按钮成功\n')
except:
    print('点击登陆按钮时出错')
​
​
#输入账号密码部分
try:
    driver._switch_to.frame(0) #这里转到fame0 因为mooc网站点击登陆后是弹窗的
    driver.find_element(By.XPATH, '/html/body/div[2]/div[2]/div[2]/form/div/div[1]/div[2]/input').send_keys(account)
    driver.find_element(By.XPATH, '/html/body/div[2]/div[2]/div[2]/form/div/div[3]/div[2]/input[2]').send_keys(password)
    print('输入账号密码成功\n')
    driver.find_element(By.XPATH, '/html/body/div[2]/div[2]/div[2]/form/div/div[8]/a').click()
except:
    print('登陆失败')
​
time.sleep(2)
#点击 我的课程 按钮
try:
    driver.switch_to.default_content()
    driver.find_element(By.XPATH,'/html/body/div[4]/div[2]/div[1]/div/div/div[1]/div[3]/div[1]/img').click()
    print("点击头像成功\n")
except:
    print("点击头像出错")
​
time.sleep(2)
#点击 高等数学(一) 课程
try:
    driver.find_element(By.XPATH,'/html/body/div[4]/div[2]/div[3]/div/div[1]/div[3]/div/div[2]/div/div/div[2]/div[1]/div[2]/div/div[1]/div[1]/div[1]/a/div[1]/img').click()
    print("点击 '高等数学(一)'成功\n")
except:
    print("点击课程失败")
time.sleep(2)
#点击继续学习
try:
    driver.switch_to.window(driver.window_handles[-1])
    driver.find_element(By.XPATH,'/html/body/div[4]/div[2]/div[4]/div[2]/div/div[1]/div/div[1]/div/div[1]/div/a[1]').click()
    print('点击继续学习成功\n')
except:
    print("点击继续学习失败")
​
​
#疯狂点击
#点击chapter后点击lesson 然后点击视频和文档
for c in chapters:
    time.sleep(1)
    
    js="document.getElementsByClassName('down f-bg j-list')[0].style.display='block'"
    driver.execute_script(js)
    driver.find_element(By.XPATH,cha+'['+c+']').click()
    
    time.sleep(1)
    for l in lessons:
        try:
            time.sleep(1)
            js2="document.getElementsByClassName('down f-bg j-list')[1].style.display='block'"
            driver.execute_script(js2)
            driver.find_element(By.XPATH,les+'['+l+']').click()
            time.sleep(1)
        except:
            break
        for i in lists:
            try:
                time.sleep(1)
                driver.find_element(By.XPATH,'/html/body/div[4]/div[2]/div[4]/div[2]/div/div[1]/div/div/div[3]/ul/li['+ i +']' ).click()
                time.sleep(1)
            except:
                break

五、最后

感兴趣的可以关注我的微信公众号,第一时间收到动态

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多