教你爬取騰訊課堂、網易雲課堂、mooc等全部課程信息

本文的全部代碼都在GitHub上託管,想要代碼的同窗請點擊這裏😸html

:因爲本身想要實現一個課程推薦系統,須要在各大視頻網站上爬取全部視頻課程,從而爲後續的推薦工做提供大量數據,在此篇博客中我分別爬取了MOOC、網易雲課堂、騰訊課堂、學堂在線共約15萬條數據。python

運行環境mysql

  1. mysqlclient~=1.4.6git

  2. requests~=2.22.0程序員

  3. bs4~=0.0.1github

  4. beautifulsoup4~=4.8.2web

MOOC

首先進入網站,在這裏咱們分析他的API設計,先要找到他是從哪個API得到相應課程的,通過分析以後咱們發現是https://www.icourse163.org/web/j/courseBean.getCoursePanelListByFrontCategory.rpc這個API,其返回內容以下:
算法

而後咱們隨意點擊頁面上的一個課程,找到其課程url的規律,打開溝通心理學這門課程,其URL是https://www.icourse163.org/course/HIT-1001515007,而溝通心理學這門課程返回的信息是:sql

// 在這裏我只保留了我須要的一些數據
{
    name: "溝通心理學",
    id: 1001515007,
    schoolPanel: {id: 9005, name: "哈爾濱工業大學", shortName: "HIT"}
}

咱們能夠發現課程的URL就是學校的簡稱-id,這樣就能夠組成課程URL,如今咱們得知課程URL如何得知,那麼這些課程數據須要傳什麼參數呢,以下:數據庫

{
    categoryId: -1, // 類別id,由於我這裏選的所有,因此是-1
    type: 30,
    orderBy: 0,
    pageIndex: 1, // 第幾頁
    pageSize: 20 // 每頁多少條數據
}

到這裏就新產生了一個問題,categoryId是怎麼來的,咱們繼續看網頁請求的api列表,找到這樣一個APIhttps://www.icourse163.org/web/j/mocCourseCategoryBean.getCategByType.rpc,其返回結果以下:

數據結構大體以下:

咱們想要獲得的課程分類特別細緻的話就須要一直向下找json的children,直到children爲空,算法的話就採用遞歸算法就能夠。

到如今爲止咱們已經知道了如何獲取類別id,若是由類別id得到課程數據,接下來咱們就須要把獲取到的數據存儲到數據庫中,個人數據庫包含類別、課程名稱、課程圖片URL、課程URL、課程來源這四個字段,存儲代碼以下:

# 存儲到數據庫
def save_to_mysql(data, category_name):
    sql = "insert into webCourses (category, name, site, imgUrl, resource) values ('{0}', '{1}', '{2}', '{3}', '{4}')".format(
        category_name, data["name"],
        'https://www.icourse163.org/course/' + str(data["schoolPanel"]["shortName"]) + "-" + str(data["id"]),
        data["imgUrl"], "慕課")
    print(sql)
    execute(sql)

要注意這裏的execute函數是我封裝的一個函數,具體的做用就是運行sql語句,所有代碼請到個人GitHub查看。

騰訊課堂

其實若是你看過了上面MOOC的獲取全部課程的API設計,其餘課程網站的API設計也是大體相同的,首先咱們要得到類別id,而後再根據類別id去請求數據,與mooc不一樣的是騰訊課堂請求課程數據是經過beautifulsoup4解析html內容實現的。下面就來簡單說一下:

獲取課程類別的API:https://ke.qq.com/cgi-bin/get_cat_info

根據類別id得到數據的網頁url: https://ke.qq.com/course/list?mt=1001&st=2001&tt=3001&page=2,這裏的mt、st、tt分別是三個類別,st是mt的一個子類,tt是st的一個子類,page就是頁數了。

獲得的網站以下:

在這裏咱們須要的是每個課程,其實思路很簡單,按F12打開開發者工具,找到課程對應的dom塊,用beautifulsoup4解析html內容,獲得課程數組就能夠了,代碼以下:

# 獲取課程數據
def get_course_data(mt, st, tt, page, category):
    url = "https://ke.qq.com/course/list?mt=" + str(mt) + "&st=" + str(st) + "&tt=" + str(tt) + "&page=" + str(page)
    response = requests.request("GET", url).text
    bs = BeautifulSoup(response)
    course_blocks = bs.find_all(name='li', attrs={"class": "course-card-item--v3 js-course-card-item"})
    # print(course_blocks)
    if len(course_blocks) != 0:
        for i in range(len(course_blocks)):
            bs = course_blocks[i]
            img = bs.find(name="img", attrs={"class", "item-img"})
            a = bs.find(name="a", attrs={"class", "item-img-link"})
            save_to_mysql(img.attrs["alt"], a.attrs["href"], img.attrs["src"], category)
        return True  # 這裏是返回該類別的下一頁是否還有數據
    else:
        return False

獲得數據以後再將這些數據存入到數據庫中就能夠了。

網易雲課堂

其實網易雲課堂就和MOOC的API設計很是相似了,畢竟都是網易公司的程序員寫的,規範也都差很少,看懂MOOC的api設計的同窗直接去個人github看代碼就能夠了。

學堂在線

學堂在線的API設計就比較簡單,直接經過一個API就能夠得到全部的數據,https://next.xuetangx.com/api/v1/lms/get_product_list/?page=1,返回的數據格式以下:

在這裏一個API裏面課程名稱、分類、課程封面URL,課程id能夠看的很是請求,下面咱們就須要獲得課程信息與課程url之間的關係,咱們隨意點開一個課程,分析他的URL,咱們就能夠發現,課程URL就是https://next.xuetangx.com/course/加上課程的course_sign組成的。

到這裏就分析結束,存儲到數據庫便可。

小結

從上述的分析咱們能夠看出,各大課程網站的api設計都是相似的,而且他們都沒有作api請求限制,因此我在爬取過程當中沒有遇到過被封IP的狀況,也算是省了很多事😂。在這裏把代碼與思路分享給你們,但願可以給到你們一些幫助。全部代碼請點擊這裏😸

相關文章
相關標籤/搜索