Python 爬蟲 好大學在線PPT

背景:上交學子肯定都用過好大學在線的慕課,可是老師上課的PPT課件只能在網頁端預覽,並不提供下載,這是非常蛋疼的一件事,畢竟上交午夜就斷網啊……

好了話不多說,這回以本人的專業課爲例,記錄下如何批量爬下一門課程的所有課件。

首先我們分析下解決的思路:

  1. 模擬登錄
  2. 分析網頁,找到PPT的鏈接
  3. 利用python解析網頁,把所有PPT鏈接保存下來
  4. 下載PPT

大概就是這樣,模擬登錄這裏爲了省事,我直接在網頁端登錄好,然後用chrome拿到cookie就能直接訪問了。

import requests
import re
from 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中拿到的登錄後的cookie
cookie = '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,有的還需要表單,這些在開發者工具裏分析的時候細心點,多嘗試,肯定能成功的……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章