資源簡(jiǎn)介
python爬蟲(chóng)相關(guān):
由于很多網(wǎng)站上的視頻只提供在線觀看,沒(méi)有下載入口,故有必要進(jìn)行網(wǎng)絡(luò)爬蟲(chóng)獲取視頻資源。
利用requests獲取網(wǎng)頁(yè)源代碼中的m3u8鏈接,對(duì)鏈接進(jìn)行逐步解析,獲取ts列表,下載所有ts文件,將其合并生成mp4文件。做到對(duì)視頻的爬取。
同名博文相關(guān)代碼。

代碼片段和文件信息
import?requests
import?os
#?字符(十六進(jìn)制)轉(zhuǎn)ASCII碼
def?hexToAscii(h):
????d?=?int(h16)???#?轉(zhuǎn)成十進(jìn)制
????return?chr(d)???#?轉(zhuǎn)成ASCII碼
#?從得到的html代碼中獲取m3u8鏈接(不同網(wǎng)站有區(qū)別)
def?getM3u8(http_s):
????ret1?=?http_s.find(“unescape“)
????ret2?=?http_s.find(“.m3u8“)
????ret3?=?http_s.find(“http“?ret1?ret2)??#?“unescape“和“.m3u8“之間找“http“
????m3u8_url_1?=?http_s[ret3:?ret2?+?5]??#?未解碼的m3u8鏈接
????#?下面對(duì)鏈接進(jìn)行解碼
????while?True:
????????idx?=?m3u8_url_1.find(‘%‘)
????????if?idx?!=?-1:
????????????m3u8_url_1?=?m3u8_url_1.replace(m3u8_url_1[idx:idx+3]?hexToAscii(m3u8_url_1[idx+1:idx+3]))
????????else:
????????????break
????return?m3u8_url_1
#?尋找字符串s中最后出現(xiàn)字符c的index
def?findLastchr(s?c):
????ls?=?[]
????sum?=?0
????while?True:
????????i?=?s.find(c)
????????if?i?!=?-1:
????????????s?=?s[i+1:]
????????????ls.append(i)
????????else:
????????????break
????for?i?in?range(len(ls)):
??????sum?+=?(ls[i]?+?1)
????return?sum?-?1
def?getM3u8_2(m3u8_url_1):
????r1?=?requests.get(m3u8_url_1)
????r1.raise_for_status()
????text?=?r1.text
????idx?=?findLastchr(text?‘\n‘)
????key?=?text[idx?+?1:]??#?得到第一層m3u8中的key
????idx?=?findLastchr(m3u8_url_1?‘/‘)
????m3u8_url_2?=?m3u8_url_1[:idx?+?1]?+?key??#?組成第二層的m3u8鏈接
????return?m3u8_url_2
#?從最原始的url-->生成一個(gè)ts列表的文件
def?getTsFile(url?filename):
????try:
????????r?=?requests.get(url)
????????r.encoding?=?r.apparent_encoding
????????r.raise_for_status()
????????http_s?=?r.text
????????m3u8_url_1?=?getM3u8(http_s)
????????print(“第一層m3u8鏈接“?+?m3u8_url_1)
????????m3u8_url_2?=?getM3u8_2(m3u8_url_1)
????????print(“第二層m3u8鏈接“?+?m3u8_url_2)
????????#?通過(guò)新的m3u8鏈接,獲取真正的ts播放列表
????????#?由于列表比較長(zhǎng),為他創(chuàng)建一個(gè)txt文件
????????r2?=?requests.get(m3u8_url_2)
????????f?=?open(filename?“w“?encoding=“utf-8“)???#?這里要改成utf-8編碼,不然默認(rèn)gbk
????????f.write(r2.text)
????????f.close()
????????print(“創(chuàng)建ts列表文件成功“)
????????return?“success“
????except:
????????print(“爬取失敗“)
????????return?“failed“
#?提取ts列表文件的內(nèi)容,逐個(gè)拼接ts的url,形成list
def?getPlayList(filename?m3u8_url_2):
????ls?=?[]
????f?=?open(filename?“r“)
????line?=?“?“??????#?line不能為空,不然進(jìn)不去下面的循環(huán)
????idx?=?findLastchr(m3u8_url_2?‘/‘)
????while?line:
????????line?=?f.readline()
????????if?line?!=?‘‘?and?line[0]?!=?‘#‘:
????????????line?=?m3u8_url_2[:idx+1]?+?line
????????????ls.append(line[:-1])????#?去掉‘\n‘
????return?ls
#?批量下載ts文件
def?loadTs(ls):
????root?=?“D://mp4//“
????length?=?len(ls)
????try:
????????if?not?os.path.exists(root):
????????????os.mkdir(root)
????????for?i?in?range(length):
????????????path?=?root?+?ls[i][-7:]
????????????r?=?requests.get(ls[i])
????????????with?open(path?‘wb‘)?as?f:
????????????????f.write(r.content)
????????????????f.close()
????????????????print(path?+?“?-->?OK?(?{}?/?{}?){:.2f}%“.format(i??length?i*100/length))
????????print(“全部ts下載完畢“)
????except:
????????print(“批量下載失敗“)
#?整合所有ts文件,保存為mp4格式
def?tsToMp4():
????print(“開(kāi)始合并...“)
????root?=?“D://mp4//“
????outdir?=?“output“
????os.chdir(root)
?屬性????????????大小?????日期????時(shí)間???名稱
-----------?---------??----------?-----??----
?????文件???????3994??2019-03-02?17:41??downloadMp4v2.py
?????文件??????67060??2019-03-01?19:32??temp.txt
?????文件??????74180??2019-03-02?17:42??ts.txt
-----------?---------??----------?-----??----
???????????????145234????????????????????3
評(píng)論
共有 條評(píng)論