1) 介绍

moodle(Modular Object-Oriented Dynamic Learning Environment) 是一个开源的课程管理系统, 笔者作为一名香港中文大学(深圳)的学生, 教授们会把课件以及作业等都发布在 moodle 上, 因此学生需要时常登录 moodle 下载课件以及完成作业. 本篇文章将简短地介绍使用 python 爬取 moodle 上的全部课件并下载到本地, 分类保存, 省去学生登录, 选择, 下载的时间, 也能更方便的在本地管理.

2) code

1. 引入模块

本篇文章将使用 requests 模块来进行爬虫的实现, 正则表达式模块re 以及对本地文件进行操作 os

1
2
3
import requests
import re
import os

2. 登录moodle

requests.Session 能够跨请求地保持某些参数,自动帮助我们处理cookies,很方便的就能够处理登录问题.

moodle没有设置反爬机制, 因此无需设置代理ip以及浏览器头部信息, 这给我们省去了不少麻烦.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
session = requests.Session()

url_post_first_page = 'https://elearning.cuhk.edu.cn/login/index.php' #香港中文大学(深圳)moodle登录url


#由于我校moodle并没有对爬虫进行任何反爬的设置, 因此header内容可不要
#header = {
# 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
# 'Referer': 'http://i.cuhk.edu.cn/cloud/pcs/moodleLogin'
#}

username = str(input('请输入用户名: '))
password = str(input('请输入密码: '))
postdata = {
'username': username,
'password': password
}

html_post = session.post(url_post_first_page, postdata) #提交表单

3. 正则表达式提取

a) 科目的提取

观察网页内容

1

2

我们使用如下表达式:"https://elearning\.cuhk\.edu\.cn/course/view\.php\?id=(.+?)"

将爬取到的url储存到一个列表中, 再次单独一个一个访问来读取每一门科目下的内容.

data = list(set(data))    #删除掉重复地址

b) 文件夹的提取

先单独访问每个科目对应的网站 (在外层套循环)

url_page = 'https://elearning.cuhk.edu.cn/course/view.php?id=' + str(num)  #num为科目对应id
page = session.get(url_page)

3

采用以下表达式

"(https://elearning\.cuhk\.edu\.cn/mod/folder/view\.php\?id=.+?)"

c) 文件的提取

"(https://elearning\.cuhk\.edu\.cn/mod/resource/view\.php\?id=.+?)"

或许大家已经发现规律了, 文件是 resource 文件夹是folder 科目是 course

4. 下载

我们定义一个函数来下载文件

def downloader(session, url, path):     #session作为参数传入, url是下载文件的地址, path是要保存的地址
    file1 = session.get(url)
    print('访问成功!开始下载')
    file = open(path, 'wb')
    file.write(file1.content)
    name = path.split('/')[-1]        #对path进行切片来提取最后的文件名, 并提示已下载成功
    print('下载成功: '+ name)
    file.close()

5. 其他

  • 创建多个字典, 来保存url对应文件或者科目等
  • 由于存在多层文件夹的嵌套, 因此要注意保存路径的编写
  • 由于存在多种格式文件, 因此要在网页源码中自己判断好文件格式并下载

3) 最后

由于笔者水平有限, 上述代码必然有许多不优秀的地方, 为了观看方便, 省略很多杂七杂八的代码, 本篇文章只能起到一个大致的思路作用, 希望能带给一些刚刚接触爬虫的小伙伴们一点思路 ( 当然笔者也是刚刚接触爬虫的小菜鸟 )

因为自己的代码写的很乱, 还存在着一些小bug, 因此笔者就不贴上代码献丑了.
当然还可以通过其他多种思路去编写爬虫, 笔者也在和大家一起进步着.