#はじめに
m3u8 を落とすソフトは無数にあるが、今回は一番シンプルにつくりたい。複雑だとブラックボックスのようになってつまらない。
#流れ
- まず m3u8 のテキストから 動画の url を取る。
- url が TS 形式なら、データを取る。
- url が m3u8 なら再帰的にデータを取る。
- 取ったデータを足す。
#コード
dl.py
import requests
import urllib.parse as up
import sys
def _dlm3u8(url,session=None,log=sys.stdout):
if not session:
session=requests.Session()
resdata=bytes()
res=session.get(url)
for line in res.text.split("\n"):
if not line: #skip empty
continue
if line[0]=="#": #skip comment
continue
vurl=up.urljoin(url,line)
if log:
print("vurl",vurl,file=log)
if ".m3u8" in vurl: #dl m3u8
resdata+=_dlm3u8(vurl,sesison=session)
elif ".ts" in vurl: #dl ts
res=session.get(vurl)
resdata+=res.content
return resdata
def dlm3u8(url,fname):
data=_dlm3u8(url)
if not data:
return False
with open(fname,"wb") as f:
f.write(data)
###_dlm3u8
引数 | 意味 |
---|---|
url | url |
返り値 | 意味 |
---|---|
data | ビデオのデータ |
##dlm3u8
引数 | 意味 |
---|---|
url | url |
fname | 書き込むファイル名 |
返り値 | 意味 |
---|---|
bool | ダウンロードの可否 |
#試す
pornhubの動画で試してみる。
main.py
import dl
url="https://ev-h.phncdn.com/hls/videos/201902/19/208607941/,200810_2009_1080P_4000K,200810_2009_720P_4000K,200810_2009_480P_2000K,200810_2009_240P_1000K,_208607941.mp4.urlset/master.m3u8?validfrom=1635132054&validto=1635139254&ipa=158.201.248.177&hdl=-1&hash=ocl5naHjd1I2e7sK9NVDL8dPLmw%3D"
fname="a.mp4"
dl.dlm3u8(url,fname)
実行結果
$ python main.py
~~ 略 ~~
vurl https://ev-h.phncdn.com/hls/videos/201902/19/208607941/,200810_2009_1080P_4000K,200810_2009_720P_4000K,200810_2009_480P_2000K,200810_2009_240P_1000K,_208607941.mp4.urlset/seg-101-f2-v1-a1.ts?validfrom=1635132054&validto=1635139254&ipa=158.201.248.177&hdl=-1&hash=ocl5naHjd1I2e7sK9NVDL8dPLmw%3D
vurl https://ev-h.phncdn.com/hls/videos/201902/19/208607941/,200810_2009_1080P_4000K,200810_2009_720P_4000K,200810_2009_480P_2000K,200810_2009_240P_1000K,_208607941.mp4.urlset/seg-102-f2-v1-a1.ts?validfrom=1635132054&validto=1635139254&ipa=158.201.248.177&hdl=-1&hash=ocl5naHjd1I2e7sK9NVDL8dPLmw%3D
vurl https://ev-h.phncdn.com/hls/videos/201902/19/208607941/,200810_2009_1080P_4000K,200810_2009_720P_4000K,200810_2009_480P_2000K,200810_2009_240P_1000K,_208607941.mp4.urlset/seg-103-f2-v1-a1.ts?validfrom=1635132054&validto=1635139254&ipa=158.201.248.177&hdl=-1&hash=ocl5naHjd1I2e7sK9NVDL8dPLmw%3D
vurl https://ev-h.phncdn.com/hls/videos/201902/19/208607941/,200810_2009_1080P_4000K,200810_2009_720P_4000K,200810_2009_480P_2000K,200810_2009_240P_1000K,_208607941.mp4.urlset/seg-104-f2-v1-a1.ts?validfrom=1635132054&validto=1635139254&ipa=158.201.248.177&hdl=-1&hash=ocl5naHjd1I2e7sK9NVDL8dPLmw%3D
~~ 略 ~~
時間はかかるが一応落とせた。
#終わりに
改良すれば早くなるのかな。こればっかりは、サーバーの問題な気もするが。。。
dlm3u8 はイテレータにすればオシャレかもしれない。(邪道な気もする。(笑))
dl.py
def _dlm3u8(url,session=None):
if not session:
session=requests.Session()
res=session.get(url)
for line in res.text.split("\n"):
if not line:
continue
if line[0]=="#":
continue
vurl=up.urljoin(url,line)
print("vurl",vurl)
if ".m3u8" in vurl:
for data in _dlm3u8(vurl,session=session):
yield data
elif ".ts" in vurl:
yield session.get(vurl).content
def dlm3u8(url,fname):
with open(fname,"wb") as f:
for data in _dlm3u8(url):
f.write(data)
for data in _dlm3u8(vurl,session=session):
yield data
は
yield from _dlm3u8(vurl,session=session)
の方が簡潔だが、肌に馴染まないので、使いたくないような。
##コード