(做完后,突然发现之前写的爬取学习通图片自动加载到ppt中那篇好傻。。。感觉白做了,不过也算是学会了一种自动建ppt的方法吧)
先直接上下载链接吧:
http://d0.ananas.chaoxing.com/download/ + mp4_objectid or ppt/pdf_objectid(如何获得ID看后文)
(ps:ppt/pdf_id可以直接把任一章节ppt中的任一图片拖到浏览器上方由新标签页打开,最长的那一串就是了)
强行偷懒直接返回下载url,没给使用者直接下载在本地。(面向自己)手动滑稽。
有时间补坑吧。。。
就先做出这样吧:
ps:最近 互联网+ 项目初步搞完了等着审核,就打算把之前学习通的坑填了,准备做个可视化的小工具;输入课程的url就可以下载ppt/pdf和mp4了。(起初我是没想到爬视频的)
最开始的设计思想是,把该课程的全部内容爬下来。所以首先是想把全部的url爬取下来。
后来发现做小工具,是给别人用的,别人自己传url就可以了诶。然后就把之前写的全删了。(ps:不过写的时候突然发现也可以爬,爬了之后提供给使用者一个csv更方便传url)
然后接下来,就是这个网站的奇葩之处了。
因为首先需要使用者传入url,所以使用者点击课程进去后,复制url再传入。
然后全部做完后,我传入url测试时,发现传回的结果都是一样的。
仔细一看才发现,进入章节后,更换章节url不会变化。如👇:
666全部都是动态加载出来的~
行吧,然后我将错就错,打算给使用者一个差的体验(手动滑稽),因为你从当前章节返回再进入你想进的章节url是会变化的。(到时候给用户个说明就行了哈哈)
那么我先爬ppt吧,but…
没办法,观察下图片的url:
前面三串没看出什么东西,这么长一坨感觉才是关键。(起初我也只是有很大感觉,后来也确实如此)
然后只有进行search大法了,在Elements中search上面“长长的一串”:
"1 of 4 " 已经get到了想要的东西了;
但是我接着往下按的时候。
没错,得到了新的objectid,也就是视频MP4的objectid。
也许看到这里有点蒙?也许会问为什么需要这个objectid呢?
接下来就知道了。
在Network中,我们同样搜索上面的objectid
可以看下列结果,第一个便是结果。后两个是加载pdf的图片。
取出下面的下载链接
下载链接:url= “http://d0.ananas.chaoxing.com/download/” +mp4_id or pdf/ppt_id
那么接下来就是如何爬取这两个id呢?
(ps:其实并不一定是两个id,万一只有mp4没有pdf/ppt,或者只有ppt/pdf没有mp4呢,所以爬取时,也需要进行判断。)
根据前文获得mp4_objectid那里,可以知道那里就是关键。如果爬取下来,既然不会动态爬取,那么就获取到相应的Response后,正则爬取下来吧。
那么这个Response在哪里呢,既然是动态加载的,那么肯定有相应的“指向”。
所以依旧search大法,屡试不爽。那么这次search什么呢?根据最开始的url,可以知道是有三个关键性ID的。如下:
我们返回,再打开另一个章节,看看哪个id变化了。
(最开始我点的是同一章的内容,发现是chapterID变化了;这里我点了不同章,看看会不会有大的变化)果然还是一样的,印证了想法:只有chapterID变化了。
所以我们在Network中search一下它。
得到两个有用的反馈。
第一个很明显是加载章节目录标题的静态网页,可以用xpath全部获取到。
第二个则需要细心观察。
preview是空的,我们看看Response
往下翻,就可以看到前面获得mp4_objectID的地方了。(这一段其实查看框架的源代码也能够看到,所以实际上,并不复杂)
打开后,也可以看到相应部分。
接下来,事情就很简单了。
获取Response后,正则爬取下来。
所以真正的url是:(其实直接查看框架源代码就有的url)
https://mooc1-1.chaoxing.com/knowledge/cards?clazzid=4176672&courseid=201678582&knowledgeid=168298554
后面可以不要//&num=0&ut=s&cpi=46415505&v=20160407-1
正则取id以及判断章节含有哪些内容:
file_id=re.findall('"objectid":"(.*?)"',res.text)
total_len=len(file_id)
file_name=re.findall('"name":"(.*?)"',res.text)
#进行判断是否有MP4/pdf
if total_len == 2:
mp4_id=file_id[0]
ppt_id=file_id[1]
mp4_name=file_name[0]
ppt_name = file_name[1]
print(mp4_name+" "+mp4_id,ppt_name+" "+ppt_id)
elif ".pdf" in res.text and ".ppt" in res.text:
ppt_id=file_id[0]
ppt_name = file_name[0]
print(ppt_name+" "+ppt_id)
else:
mp4_id=file_id[0]
mp4_name = file_name[0]
print(mp4_name+" "+mp4_id)
得到结果
DSP 1-1 DSP技术的基本概念.mp4 169e68aa4122f842d4512d61dbe7921c DSP第1章1.1(1).pdf 8418560aa9ce42b0c5de0cab8ebe89f1
故得到了我们想要的结果。
接下来就是如何通过传入的url取得所需要的id呢?
所以根据上面的url其实已经可以猜到了。
chapterID = knowledgeID
所以用户传入的url,取出三个ID,把真正的url格式化。就可以了
url = "https://mooc1-1.chaoxing.com/mycourse/studentstudy?chapterId=168298554&courseId=201678582&clazzid=4176672&enc=875ecd40b025e42e40e8f851e6d05756"
pat1 = 'clazzid=(.*?)&'
pat2 = "courseId=(.*?)&"
pat3 = "chapterId=(.*?)&"
#pat2 = "c(.*?)id"
#clazzid = re.match(pat1, url)
clazzid = "".join(re.findall(pat1,url))
courseid = "".join(re.findall(pat2,url))
knowledgeid = "".join(re.findall(pat3,url))
real_url="https://mooc1-1.chaoxing.com/knowledge/cards?clazzid={0}&courseid={1}&knowledgeid={2}".format(clazzid,courseid,knowledgeid)
print(real_url)
得到结果
https://mooc1-1.chaoxing.com/knowledge/cards?clazzid=4176672&courseid=201678582&knowledgeid=168298554
下载就用个函数
mp4_url="http://d0.ananas.chaoxing.com/download/{0}".format(mp4_id)
ppt_url = "http://d0.ananas.chaoxing.com/download/{0}".format(ppt_id)
##记得加headers
ppt_res=requests.get(ppt_url,headers=headers)
mp4_res = requests.get(mp4_url, headers=headers)
##这里试验一下ppt的下载
with open(ppt_name,"wb") as f:
f.write(ppt_res.content)
print("下载完成")
f.close()
接下来就是如何做成可视化的(感兴趣的小伙伴可以学习下tkinter)
做完后,我发现还需要一个登录UI…毕竟是要cookies的(补坑补坑)
有时间更新中。。。
抽时间更新一下吧,给个传入cookies的输入框。直接传入链接,不传入cookies则弹出“越权”。(但是每次都要传入cookies还是很麻烦,将cookies保存在本地,每次点击读取就更方便了)=,=不过这个我不会,其实是失败了,感兴趣的小伙伴们可以百度下这方面的知识。
这里作判断,传入cookies授权以及url是否正确
##之前的下载不变
##这里作判断 是否传入cookies以及url是否正确
except:
res=requests.get(url,headers=headers)
dom=etree.HTML(res.content)
title=dom.xpath('//*[@id="body_0x003"]/h2/text()')
if title:
showerror("越权","请先登录")
else:
showerror("错误", "请输入正确完整的章节url")
最后还是直接附上download吧
def download():
cookies = entry0.get().strip()
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36',
'Cookie': cookies
}
url = entry1.get().strip()
try:
#url = "https://mooc1-1.chaoxing.com/mycourse/studentstudy?chapterId=168298554&courseId=201678582&clazzid=4176672&enc=875ecd40b025e42e40e8f851e6d05756"
pat1 = 'clazzid=(.*?)&'
pat2 = "courseId=(.*?)&"
pat3 = "chapterId=(.*?)&"
# pat2 = "c(.*?)id"
# clazzid = re.match(pat1, url)
clazzid = "".join(re.findall(pat1, url))
courseid = "".join(re.findall(pat2, url))
knowledgeid = "".join(re.findall(pat3, url))
real_url = "https://mooc1-1.chaoxing.com/knowledge/cards?clazzid={0}&courseid={1}&knowledgeid={2}".format(
clazzid, courseid, knowledgeid)
res = requests.get(real_url, headers=headers)
'''
mp4_url = "http://d0.ananas.chaoxing.com/download/{0}".format(mp4_id)
ppt_url = "http://d0.ananas.chaoxing.com/download/{0}".format(ppt_id)
##记得加headers
ppt_res = requests.get(ppt_url, headers=headers)
mp4_res = requests.get(mp4_url, headers=headers)
with open(ppt_name, "wb") as f:
f.write(ppt_res.content)
print("下载完成")
'''
file_id = re.findall('"objectid":"(.*?)"', res.text)
total_len = len(file_id)
file_name = re.findall('"name":"(.*?)"', res.text)
if total_len == 2:
mp4_id = file_id[0]
ppt_id = file_id[1]
mp4_name = file_name[0]
ppt_name = file_name[1]
# print(mp4_name + " " + mp4_id, ppt_name + " " + ppt_id)
mp4_url = "http://d0.ananas.chaoxing.com/download/{0}".format(mp4_id)
ppt_url = "http://d0.ananas.chaoxing.com/download/{0}".format(ppt_id)
input_parm.set(mp4_url)
input_parm1.set(ppt_url)
elif ".pdf" in res.text and ".ppt" in res.text:
ppt_id = file_id[0]
ppt_name = file_name[0]
# print(ppt_name + " " + ppt_id)
ppt_url = "http://d0.ananas.chaoxing.com/download/{0}".format(ppt_id)
input_parm1.set(ppt_url)
input_parm.set("无MP4资源")
else:
mp4_id = file_id[0]
mp4_name = file_name[0]
mp4_url = "http://d0.ananas.chaoxing.com/download/{0}".format(mp4_id)
input_parm.set(mp4_url)
input_parm1.set("无ppt/pdf资源")
# print(mp4_name + " " + mp4_id)
except:
res=requests.get(url,headers=headers)
dom=etree.HTML(res.content)
title=dom.xpath('//*[@id="body_0x003"]/h2/text()')
if title:
showerror("越权","请先登录")
else:
showerror("错误", "请输入正确完整的章节url")