非程序背景出身研究生,自学python写的下载器。学了4天爬虫,花了一星期写的代码。初衷是为了下载课件节省时间和练习网络爬虫。
我想除了中丹学院的学生很少有人会用到这个的,国内几乎没有用Moodle的,写这篇帖子主要是为了给想写网络爬虫和设计极简GUI一点参考。下面看下成品效果吧。

Moddle-Slide-Downloader1.特性:写的程序比较邪门,快的时候很快,慢的时候有点慢,但是优点是全自动化。

l 不用打开浏览器
l 不用解压文件,不用建文件夹
l 除了第一步输入课程链接和账号密码啥的,以后都是鼠标点三下自动同步文件)干别的时候挂在就行了,估计也节省不了很多时间2.用法:

3.打开软件
不要关闭电脑cmd,cmd是作为软件输出的信息的。(本来想用PySimpleGUI作为输出信息的,比cmd好看多了,无奈太卡,只能cmd了)4.输入
账号密码
课程储存路径
课程链接地址:复制链接粘到软件5.第一次使用点击SaveSettings

会在软件同目录保存一个配置文件用来保存用户账号、密码、路径、课程URL等
(尽量不要把软件放在桌面,尤其是开启桌面清理的情况下,软件容易无法建立配置文件,可以放在其他盘,然后建立快捷方式)
你原先建的课程文件夹及下面包含的文件夹一定要和Moddle的一样,不然就会重新下载文件。6. 再次打开先点击loadsetting,再点击 submit.7. 文件下载过程会把课件文件信息罗列一遍,并且在最后生产生产文件更新报告。

文件小于0.1M会出现进度条问题,设计到API底层问题,解决不了。

很多时候软件不如手动下载快,我还很vegetable,不过全自动的挂在呗。 下面代码奉上。初学爬虫,性能不足,很多地方有待改进,欢迎高人指点。也欢迎萌新借鉴。

import time
import requests
from bs4 import BeautifulSoup
import os
import re
# import dill
import PySimpleGUI as sga = time.time()
# dill.load_session('file_name.pkl')
# dill.dump_session('file_name.pkl')#定义一个空集合用来保存更新的文件
update_slides = []
#获取课程url信息def getHTML(url):try:r = sessions.get(url, timeout=60, headers=hd)r.raise_for_status()  # 容错机制,若请求访问失败则返回的不是200,则返回字符串空r.encoding = r.apparent_encoding  # 设置编码方式,用解析返回网页源码得出的编码方式代替  UTF-8return r.textexcept:return ''#定义解析HTML函数
def soupanyl(course_url):text = getHTML(course_url)  # 获得课程主页面storage,减少重复运算soup = BeautifulSoup(text, 'html.parser')return soup#定义文件保存函数
def save_files(file_url, local_path, course_title, section_name, first_folder_name, file_name):global update_slidesfile_path = local_path + '/' + course_title + '/' + section_name + '/' + first_folder_name + '/' + file_namestore_path = file_path.replace(file_path.split('/')[-1], '')new_file = course_title + '/' + section_name + '/' + first_folder_name + '/' + file_nameif not os.path.exists(store_path):os.makedirs(store_path)if not os.path.exists(file_path):try:print('新上了一个文件正在准备下载' + new_file)start = time.time()response = sessions.get(file_url,stream=True)  # stream参数设置成True时,它不会立即开始下载,当你使用iter_content或iter_lines遍历内容或访问内容属性时才开始下载chunk_size = 1024  # 每次块大小为1024content_size = int(response.headers['content-length'])  # 返回的response的headers中获取文件大小信息size_data = str(round(float(content_size / chunk_size / 1024), 4))print("    文件大小:" + size_data + "[MB]")print('  ', end='')with open(file_path, 'wb') as file:count = 0for data in response.iter_content(chunk_size=chunk_size):  # 每次只获取一个chunk_size大小file.write(data)  # 每次只写入data大小count += 1024proced = int(round(100 * count / content_size))print(('r    进度: {}%' + '█' * round(proced / 2) + '>' * (50 - round(proced / 2))).format(proced),end='')  # 向终端输出#  [ r 加上文本 加 end = ''是单行刷新)end = time.time()print("n    该文件下载成功,总耗时:" + str(end - start) + "秒", end='n')print('', end='n')update_slides.append(new_file)except:print('    网络或其他原因,该文件下载失败。download failed')else:print('    该路径下文件已经存在:' + new_file)#从HTML解析出文件名
def seg(url):before = re.findall(r'/0/.+?forcedownload', url)[0][3:-14].replace('%20', ' ')return before#一部分文件名存在课件下载url链接中,但是在重新定向的文件中,定义两个函数重新定向获取url里的文件名
def redirect_url_name(url):# 获取pdf连接后名字的爬取redirect = sessions.get(url, timeout=60, headers=hd)# print(sessions.status_code)  # 打印响应的状态码return redirect.url  # 打印重定向后的网址def get_redi_name(url):redi_url = redirect_url_name(url)name = re.findall(r'/content/./.+', redi_url)[0][10:].replace('%20', ' ')return name#解析的文件夹名中删除那些建立文件夹不合法的特殊字符
def ex_odd(txt):for ch in "/:*?''<> |":txt = txt.replace(ch, " ")return txt#获得课程标题
def getitle(url):try:soup = soupanyl(url)title = soup.h1.stringif title[0] == ' ':title = title[1:]return titleelse:title = titlereturn titleexcept:return 'unknow'#定义下载某一课程的所有课件
def get_course_all_slides(course_url, local_path):soup = soupanyl(course_url)materials = soup('li', id=re.compile('section'))  # get section htmlcourse_title = getitle(course_url)for section in materials:try:infos = section('a')section_name = section.span.stringsection_name = ex_odd(section_name)for info in infos:try:url1 = info.get('href')if 'resource/' in url1:file1_name = get_redi_name(url1)first_folder_name = ''save_files(url1, local_path, course_title, section_name, first_folder_name, file1_name)elif 'download' in url1:first_folder_name = ''file2_name = seg(url1)save_files(url1, local_path, course_title, section_name, first_folder_name, file2_name)elif '/folder/' in url1:file_or_folder_name = info.span.contents[0]soup2 = soupanyl(url1)materials2 = soup2('div', role='main')msgs = materials2[0]('a')for msg in msgs:try:url2 = msg.get('href')file3_name = seg(url2)save_files(url2, local_path, course_title, section_name, file_or_folder_name,file3_name)except:continueelse:continueexcept:continueexcept:continue
#开始访问并登录网站,session用来保存网站的cookie信息,换句话说就是记中账号密码,如果不是这样,后边的url解析都是未登录状态。
sessions = requests.session()
hd = {'user-agent': 'chorme/10'}        #定义浏览器标头,防止爬虫禁止的条令
def login(UserName,PassWord):print('    准备进入Moodle....(这个网站会卡,正常的,别担心,等等就好,如果一直进不去的话的话打开浏览器看看卡不卡,要是也卡的话就不是我的锅了,我是robot,和你手动下载一样的,不用你点点点了),Preparing for entering Moodle.......')loginurl = 'https://sdc-moodle.samf.aau.dk/login/index.php'data = {'username': UserName, 'password':PassWord}request = sessions.post(url=loginurl, data=data, headers=hd)new_lo = request.urlreturn new_lo == loginurl #返回是否登录成功的信息,True代表未成功,False是成功的,如果登录成功url会改变。##下面是url设计 PysimpleGUI是一种很简单的GUI库,可以在很短的周期学会,很适合没有时间学习第三方GUI库的初学者甚至熟练的程序猿。sg.ChangeLookAndFeel('TanBlue')     #GUI主题# Design pattern 1 - First window does not remain active
#设计GUI布局
layout = [[sg.Text('Moodle-Slides-Downloader for SDC students',font=("Reds", 25),size=(45, 1))],[sg.Text('账号(UserName):',font=(15)),sg.Input(key = '_USER_',size=(30, 1))],[sg.Text('密码(Password):',font=(15)),sg.Input(password_char='*', key='_PWD_',size=(30, 1)),],[sg.Text('路径(Filepath):',font=(15)),sg.InputText('Select your curricula storage path',key = '_PATH_'), sg.FolderBrowse()],[sg.Checkbox('',default= True,key = 'cs1'),sg.Text('课程1(Course1):', font=(15)), sg.InputText('Please input your course URL', size=(60, 1),key = 'course1')],[sg.Checkbox('',default = True,key = 'cs2'),sg.Text('课程2(Course2):', font=(15)), sg.InputText('Please input your course URL', size=(60, 1),key = 'course2')],[sg.Checkbox('',default = True,key = 'cs3'),sg.Text('课程3(Course3):', font=(15)), sg.InputText('Please input your course URL', size=(60, 1),key = 'course3')],[sg.Checkbox('',default = True,key = 'cs4'),sg.Text('课程4(Course4):', font=(15)), sg.InputText('Please input your course URL', size=(60, 1),key = 'course4')],[sg.Btn('SaveSettings'),sg.Button('LoadSettings'),sg.Btn('Submit')],
]#设计GUI页眉
win = sg.Window('中丹学院(Sino-Danish Center)     @Jinglu Han     version1.0', layout)
#设置主事件循环,保持窗口一致打开,供用户输入信息while True:ev, vals = win.Read()filename = 'Moodle_downloader_save.sav'if ev == 'SaveSettings':try:win.SaveToDisk(filename)        #PySimpleGUI里面的保存设置按钮,找了很久的API,供大家参考sg.popup('sucessfully saved')except:sg.popup('Please select your storage path')elif ev == 'LoadSettings':win.LoadFromDisk(filename)# load(form)if ev is None:breakif ev == 'Submit':judge = login(vals['_USER_'],vals['_PWD_'])if judge:sg.popup('login failed,please check your account or password')else:sg.popup('sucessfully login in,start downloading')print('    成功进入Moodle,sucessfully login in Moodle')for  i in range(4):try:T = vals['cs' + str(i+1)]if T:course_url = vals['course' + str(i+1)]local_path = vals['_PATH_']get_course_all_slides(course_url, local_path)else:continueexcept:continueb = time.time()print('程序运行时间:{:.2f}秒'.format(b - a))print('程序运行时间:{:.2f}分'.format((b - a) / 60))print('更新以下文件:(Below files have been downloaded)')for update in update_slides:print(update + '已下载(has been downloaded)')

如果有中丹学院的学弟学妹们,欢迎使用这个小软件。如果bug,欢迎留言反馈,反正我也不会改的(滑稽)。 有问题的话欢迎留言,看到都会回复的,加油,奥力给!

资源链接:链接:https://pan.baidu.com/s/1ZTd3_aW6cMLVBDRHGk_98A

提取码:lha0

复制这段内容后打开百度网盘手机App,操作更方便哦

moodle重定向_用最简单的pythonGUI库PysimpleGUI 设计一款中丹学院Moodle课件下载器。...相关推荐

  1. unity三维地图的经纬度如何在二维地图上表示_接入C++版本recastnavigation寻路库到Unity/服务端中...

    前言 因为Unity版本的更新迭代,老版本的A*插件在新版本Unity已经无法正常使用,包括一些运行时代码也已经过时,重新接入要花费很多时间,干脆接入一个新的寻路方案吧. 这里选择的是久负盛名的htt ...

  2. 如何用matlab进行部分式展开_高数简单问题:真分式化成部分分式之和题目,MATLAB中对多项式进行部分分式展开。...

    用MATLAB进行部分分式展开 MATLAB有1个命令用于求B(s)/A(s)的部分分式展开式. 设s的有理分式为 式中 (i=)和(j=)的某些值可能为零.在MATLAB的行向量中,num和den分 ...

  3. 动漫的python语言代码_由Python编写的全异步实现的动漫之家(dmzj)漫画批量下载器(爬虫)...

    DCDownloader 专注于漫画网站.图站等类似形式的内容站点的批量下载器框架. 说明 这个项目最开始是作者编写的一个仅支持某个漫画网站的批量下载器,后来有人提建议说有增加网站的需求,作者便重新梳 ...

  4. 【Android】 简单的朋友圈界面设计

    Android 简单的朋友圈界面设计 在Eclipse中创建Android项目,名称为friend 修改新建项目的res/layout目录下的布局文件activity_main.xml,将默认添加的布 ...

  5. react 路由重定向_如何测试与测试库的路由器重定向React

    react 路由重定向 React testing-library is very convenient to test React components rendering from props, ...

  6. 05-Flutter移动电商实战-dio基础_引入和简单的Get请求

    05-Flutter移动电商实战-dio基础_引入和简单的Get请求 这篇开始我们学习Dart第三方Http请求库dio,这是国人开源的一个项目,也是国内用的最广泛的Dart Http请求库. 1.d ...

  7. usb禁止重定向_一种USB重定向处理方法和系统与流程

    本发明涉及桌面虚拟化的USB重定向处理技术领域,具体而言,涉及一种USB重定向处理方法和系统. 背景技术: 随着科学技术的不断进步,网络技术日益发达,虚拟化的应用逐渐普及.桌面虚拟化是指在数据中心的服 ...

  8. SpringCloud学习笔记018---SpringBoot前后端分离_集成_SpringSecurity_简单实现

    SpringBoot前后端分离_集成_SpringSecurity_简单实现 1.新建SpringBoot项目,可以使用idea,快速创建    file-create-project->选择w ...

  9. 查询计算机系学生的详细记录,实验三_数据库的简单查询和连接_.doc

    实验三_数据库的简单查询和连接_ 实验三 数据库的简单查询和连接查询 实验目的及要求 掌握SELECT语句的基本语法: 熟练掌握表的数据简单查询.数据排序: 熟练掌握表的连接查询的表示: 掌握等值连接 ...

  10. unity重定向_动画重定向技术分析和Unity中的应用

    0. 前言 新的手游项目使用Unity引擎,动画部分要使用重定向技术来实现动画复用.之前在大公司工作的时候对这块了解比较深入,读过Havok引擎在这部分的实现源码,也基于自己的理解在公司自研的手游引擎 ...

最新文章

  1. php 限制刷新,PHP禁止频繁刷新方法
  2. pandas使用replace函数将dataframe中None值以及其他异常编码值(例如,9999)替换为np.nan
  3. boost::foreach模块一些杂项的测试程序
  4. 数字图像处理实验三图像增强
  5. android 图片叠加xml,Android实现图片叠加效果的两种方法
  6. 常用MIME类型,解决IIS布署后字体文件、mp4视频文件等not found 的错误
  7. [转]JS部分通用函数
  8. WindowsAPI----AttachThreadInput使用
  9. 一个准毕业生的2012年总结
  10. 计算机网络中TCP连接管理,计算机网络 TCP协议
  11. Genymotion安装apk问题,不能部署Genymotion-ARM-Translation_v1.zip
  12. leetcode-22-括号生成
  13. JavaScript GET 和 POST 请求的区别详解
  14. STM32F103C8的keil环境配置和STlink烧录
  15. 开发服务器 k8s 设置 自定义 dns解析
  16. LeetCode笔记:Biweekly Contest 37 比赛记录
  17. c语言钟表程序,制作一个电子时钟C语言版
  18. JZOJ 1266. 玉米田
  19. 【练习题】第二章--变量,表达式,语句(Think Python)
  20. 5款开源云计算平台推荐

热门文章

  1. plsql破解的办法
  2. Backtrack 算法思路
  3. python获取列表控件_PyQt学习随笔:ListView控件获取当前选择项的方法
  4. android模拟win98中文版,Win98模拟器
  5. 如何通过SCJP考试(含真题分析和考点)
  6. 《乔布斯传.神一样的传奇》读后感
  7. 寻找可接入正版音乐曲库的音乐API?来了解HIFIVE音乐开放平台!
  8. BXP无盘的更新操作详解(大镜像)(转)
  9. java excel换行_Java 导出excel进行换行的案例
  10. 白盒测试方法与黑盒测试方法简析