(做完後,突然發現之前寫的爬取學習通圖片自動加載到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")