今天介紹如何爬取奇安信認證培訓平臺上已經(jīng)購買的視頻課程。
環(huán)境
- windows 7 x64
- python2.7.16
- Firefox開發(fā)版
- vscode 編輯器
- 依賴庫 requests,bs4,js2py
總體思路
1. 打開頁面 完成登陸鑒權(quán)
登陸鑒權(quán)我們使用了瀏覽器中的cookie, 這些信息可以從瀏覽器中拷貝,cookie信息在模擬登陸中會用到

HTTP請求頭中的cookie

請求的cookie
2. 從課程頁面中提取出課時的url和title
課程頁面中的課時列表,利用bs4庫可以輕松提取這些課時的url和title

image.png
3. 從課時頁面中提取出視頻的下載url,下載視頻保存到本地
用瀏覽器打開課時頁面,會正常播放視頻,但是用requests請求頁面,返回的html文檔不含有視頻的播放地址。分析發(fā)現(xiàn),頁面使用js加載了一個視頻播放控件,在js中生成視頻的播放地址。
在html文檔的25行有一個H5PIntegration變量,存儲有視頻的播放參數(shù)。

image.png

image.png
使用js2py可以在python代碼中運行js代碼。通過這個庫可以得到H5PIntegration變量的值。
代碼實現(xiàn)
#-*- coding:utf-8 -*-
#writen by wlj @2020-2-20 13:52:33
import json
import js2py
import requests,re,os
from requests.packages import urllib3
urllib3.disable_warnings()
from bs4 import BeautifulSoup
#全局變量
#http headers
cookie_str = 'xxxx'
#使用用戶名和密碼登陸后,在瀏覽器的console中輸入document.cookie復制即可
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0',
'Referer':'https://learning.b.qianxin.com/my/',
'Cookie':'MoodleSession=%s' % cookie_str
}
cookies = {"MoodleSession":cookie_str}
#requests的會話對象
s = requests.Session()
#根據(jù)視頻頁面的url將視頻保存為指定文件
def download_video(url,filename):
r= s.get(url,headers=headers,verify=False,cookies=cookies)
if r.status_code == 200:
#找到頁面中這一段js代碼,里面有視頻url信息
a = re.findall(r'(var H5PIntegration = .*?;)',r.text)
#使用js2py庫來加載這段js,并輸入變量H5PIntegration
H5PIntegration = js2py.eval_js(a[0]+'H5PIntegration')
#得到視頻的url前綴
key=''
prefix = ''
for k in H5PIntegration['contents']:
if k.startswith('cid'):
key = k
prefix = H5PIntegration['contents'][k]['contentUrl']
break
#得到視頻的路徑
jsonContent = H5PIntegration['contents'][key]['jsonContent']
path = json.loads(jsonContent)['interactiveVideo']['video']['files'][0]['path']
#拼接成完整的url
video_url = str(prefix)+'/'+path
print(video_url)
#視頻的播放地址如 'https://learning.b.qianxin.com/pluginfile.php/55100/mod_hvp/content/518/videos/files-5d6c70eb9e021.mp4'
#下載視頻文件
res1 = s.get(url = video_url, headers=headers,stream=True,verify=False)
with open(filename, "wb") as f:
for chunk in res1.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
print(filename,'downloaded!')
#爬蟲主函數(shù)
def main():
#課程的url
url = 'https://learning.b.qianxin.com/course/view.php?id=28'
r = s.get(url,headers=headers,verify=False)
if r.status_code == 200:
#利用bs4庫從頁面html文檔中解析出課程各課時的title和url
soup = BeautifulSoup(r.text,'lxml')
for li in soup.find_all('li',class_=['section', 'main', 'clearfix'])[1:-1]:
#課程的章節(jié)名稱,如“第一天”
chapter_name = li['aria-label'].strip()
#構(gòu)造課程的保存路徑
dir_path = 'data\\%s' % chapter_name
#不存在的話,將其創(chuàng)建
if not os.path.isdir(dir_path):
os.makedirs(dir_path)
print(chapter_name)
#提取本章節(jié)中所有的課時的title和url
for a in li.ul.find_all('a'):
#課時頁面的url
href = a['href']
#課時的title
title = a.text.strip().split(' ')[0]
#print(title)
#print(href)
#構(gòu)造文件名,去掉不合法的字符
illege_chars = ['<','>','/','\\','|',':','"','*','?']
for char in illege_chars:
title = title.replace(char,'_')
#視頻最終的文件名
filename = dir_path + os.sep + title + '.mp4'
#print(filename)
#若該視頻沒被下載,將其下載到本地
if not os.path.isfile(filename):
download_video(href,filename)
main()
腳本使用方法
首先打開Firefox,使用合法的用戶名和密碼登陸網(wǎng)站(https://learning.b.qianxin.com)后,打開開發(fā)者工具的console選項卡,輸入document.cookie即可獲取到用戶的cookie,將其中的MoodleSession的值賦值給腳本中的cookie_str變量,運行腳本即可下載課程了。
結(jié)果

image.png