背景:上交学子肯定都用过好大学在线的慕课,可是老师上课的PPT课件只能在网页端预览,并不提供下载,这是非常蛋疼的一件事,毕竟上交午夜就断网啊……
好了话不多说,这回以本人的专业课为例,记录下如何批量爬下一门课程的所有课件。
首先我们分析下解决的思路:
模拟登录
分析网页,找到PPT的链接
利用python解析网页,把所有PPT链接保存下来
下载PPT
大概就是这样,模拟登录这里为了省事,我直接在网页端登录好,然后用chrome拿到cookie就能直接访问了。
import requestsimport refrom bs4 import BeautifulSoup headers = {"User-Agent": 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', 'X-Requested-With': 'XMLHttpRequest'}# 这是我课程的导航页,所有章节都可以在这看到nav_page = 'https://cnmooc.org/portal/session/unitNavigation/10036.mooc'#这是从chrome中拿到的登录后的cookiecookie = 'moocvk=a9628796e8c3450a85791954be220ee6; sos=true; moocsk=f3f8b5550828439c932b0fe033d74c29; JSESSIONID=225C396119183B79BE506D97B9AAC5F2.tomcat-host1-1; Hm_lvt_ed399044071fc36c6b711fa9d81c2d1c=1539508316,1539508326,1539579539,1539589878; Hm_lpvt_ed399044071fc36c6b711fa9d81c2d1c=1539589908; BEC=f6c42c24d0c76e7acea242791ab87e34|1539592046|1539579539'# 这个函数把上面这个cookie字符串转化为python字典def extract_cookies(cookie): """从浏览器或者request headers中拿到cookie字符串,提取为字典格式的cookies""" cookies = dict([l.split("=", 1) for l in cookie.split("; ")]) return cookies
好,第一步over,第二步也很简单。随便打开一个章节PPT的网页页面,然后f12打开开发者工具,在element标签下搜索ppt
这个关键词…直到我发现/repositry/resource/d/1703/27/0cced6dba98d4e5a9977d7b83da3bb04.pptx
这一串,我知道我成功了!把完整的地址输入chrome,果然不用登录都可以直接下载了。
再来第三步,把这些ppt的地址都存下来。显然这是经过加密的,找不到规律啊,所以只能一个个爬。这并不麻烦啊,每个PPT的id都在导航页。
def get_all_links(cookies): s = requests.session() r = s.get(nav_page, headers=headers, cookies=cookies) html = r.text soup = BeautifulSoup(html) # lecture-action linkPlay 是ppt对应的class, 下面这行找到ppt所在的a标签,我们同时存下id和ppt的名字,后面就好给文件命名了。 a = soup.find_all('a', "lecture-action linkPlay", title=re.compile("pptx")) itemid = [] titles = [] for item in a: itemid.append(item['itemid']) titles.append(item['title']) return itemid, titles
这一步只是拿到ppt所在网页的id,也就相当于ppt页面的网址。那么ppt资源的地址其实还没拿到。我开始以为就在这个页面里,后来发现并不是,那个资源地址其实在一段js代码内。于是,在开发者工具的network标签下继续搜索ppt,找到这个ppt资源的地址其实是在https://cnmooc.org/study/play.mooc
这个页面下的,并且该页面用的是post方式提交,注意同时还要提交一个表单。代码如下:
def get_resource_links(cookies, unitid): url = 'https://cnmooc.org/study/play.mooc' base = 'https://cnmooc.org' res_links = [] for id in unitid: data = {'itemId': id, 'itemType': '20', 'testPaperId':''} s = requests.session() r = s.post(url, data, cookies=cookies) try: res_links.append(base + re.search('/repositry/.*\.pptx',r.text).group()) except AttributeError: print("not found") return res_links
这样其实就拿到所有资源的地址了,最后一步很简单就是下载啦,随便百度了一下,就有源码:
def save_files(): for i in range(0, len(res_links)): html = requests.get(res_links[i], headers=headers) with open(titles[i], 'wb') as file: file.write(html.content) save_files()
省略了部分代码,大意就是这样。具体的情况还是要具体分析。其中我入了不少坑也不多说了,重点要细心一点,提交请求的时候有的需要cookie,有的还需要表单,这些在开发者工具里分析的时候细心点,多尝试,肯定能成功的……
作者:黑冰561
链接:https://www.jianshu.com/p/abde80043ce4
共同学习,写下你的评论
评论加载中...
作者其他优质文章