這幾天想看灌籃高手的動漫,可是發現愛奇藝,搜狐等視頻網站只有灌籃高手標清的,2013年的重製高清版都下架不能看,好像由於版權問題沒法播放了,因而百度上搜索,在m.dm530.net/show/4154.html 上還有灌籃高手的重製高清版在線觀看,可是在線觀看不知是瀏覽器問題仍是什麼,沒法快進和後退,反正就各類問題,因而就想用Python把該網站的視頻直接下載到本地,這樣關鍵的問題就是要找到視頻的真實URL。javascript
首先是想辦法先獲取第一集視頻的URL,因而使用谷歌瀏覽器打開第一集的播放地址m.dm530.net/v/4154-0-0.html ,按F12,打開Chrome DevTools,選擇network選項,去查看網絡請求的數據包,看視頻連接會不會出如今那裏,按文件大小進行排序後,發現有個60M的文件,以下圖
這文件頗有可能就是視頻連接了,把連接複製下來php
http://edge.ivideo.sina.com.cn/118657395.hlv?KID=sina,viask&Expires=1525104000&ssig=qqeUdXnlpO
發現是新浪的網址,而後去百度了hlv格式,查到了這也是新浪視頻的文件格式。這應該就是所要找的視頻連接,下載測試發現是能正常播放的,不過是要支持flv文件格式的播放器才行。並且下載的視頻也只有6分鐘,應該是新浪把視頻分段了。獲取了不一樣的視頻URL,進行比較,發現URL中 文件名稱(也就是118657395.hlv)和ssig參數會變化,域名和KID=sina,viask&Expires=1525104000這兩個參數是沒有變化的。因而只要找到文件名和ssig參數的數據就能夠獲取到拼接成視頻URL了。
因而繼續在chrome瀏覽器在查看網絡請求的數據包,發現了有個XML文件,其中包含着一集視頻的全部URL地址和視頻信息。不過這獲取這XML的連接是有時間限制的,一會後就不能訪問了。連接和截圖以下所示:html
https://player.s1905.com/ipsign/parse.php?url=118656937_sina&sign=98062c84b16523141973ac1e&ran=1525008246&ipsign=83753ccabbae12d1f05053a3a18ec96b1d6962fb802e7585d7101af33f76b43acd270e87&ip=自身IP
因而思考這XML連接是怎麼獲取的,繼續查看請求的數據包,沒發現什麼有用的信息了。。。。因而我直接查看網頁的源代碼,看看源代碼是經過什麼方式獲取該連接的,看到播放頁面處就只有下面的js代碼。java
<script type="text/javascript" src="/playdata/58/4154.js?6195.856"></script><script>var param=getHtmlParas('.html');viewplay(param[0],param[1])</script>
看來網站是經過這js代碼獲取XML連接的。因而繼續查看網站的js文件,看到不少加密的js文件,原本就對js不熟了,更別說混淆加密後的js了,更無從入手了。
因而繼續去Chrome DevTools中各類選項看看有沒有什麼信息遺漏的,忽然看到Chrome DevTools的elements選項的HTML代碼中還有個iframe標籤,以前直接查看源代碼中是沒有顯示着iframe標籤的。
這應該是HTML的一些特性吧,我也不太瞭解,查看iframe標籤的代碼,終於發現關鍵信息了,以下圖:
裏面js代碼的變量就是XML連接的各類參數python
XML網址:https://player.s1905.com/ipsign/parse.php?url=118656937_sina&sign=98062c84b16523141973ac1e&ran=1525008246&ipsign=83753ccabbae12d1f05053a3a18ec96b1d6962fb802e7585d7101af33f76b43acd270e87&ip=自身IP
也就是隻要獲取到iframe標籤的這些JS變量值,咱們就能夠獲取到獲取視頻地址的XML,從上圖中能夠看到,url、ran和ip參數都已經給出來了,剩下須要獲取的就是隻有ipsign和sign這兩個參數的值了。
但是ipsign和sign這兩個變量使用的JS函數,在混淆加密的JS文件中,根本就看不出來邏輯,以下圖:
手動分析JS代碼看來是行不通的了,因而我百度下看到了些思路,還能夠模擬瀏覽器運行,從而獲取JS變量值的。
查到Python能夠經過selenium庫模擬真實瀏覽器去渲染JavaScript的。web
具體實現方式就是Python使用selenium去運行chrome瀏覽器(要下載chrome瀏覽器對應的chromedriver),返回JS變量值。由於video變量的值比所須要的XML的網址只是多了兩個參數,因此就直接獲取video變量的值再截取成XML網址,獲取XML後,再使用正則表達式匹配視頻URL。正則表達式
XML網址:https://player.s1905.com/ipsign/parse.php?url=118656937_sina&sign=98062c84b16523141973ac1e&ran=1525008246&ipsign=83753ccabbae12d1f05053a3a18ec96b1d6962fb802e7585d7101af33f76b43acd270e87&ip=自身IP video變量:var video = 'https://player.s1905.com/ipsign/parse.php?url=' + encodeURIComponent(url) +'&ctype=phone&hd=3&sign=' + sign +'&ran=' + ctime +'&ipsign=' + ipsign +'&ip=' + ip +'';
具體代碼:chrome
# _*_ coding: utf-8 _*_ import threading import os import re from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.options import Options import requests import time def getvideo(url,filename): #設置瀏覽器選項 chrome_options = Options() chrome_options.add_argument("--headless") #啓動Chrome 瀏覽器的×××面形態 #對應的chromedriver的放置目錄,由於個人chromedriver放進python安裝目錄的Scripts,因此能夠不填 driver = webdriver.Chrome(chrome_options=chrome_options) #瀏覽器瀏覽網址 driver.get(url) try: driver.switch_to.frame(0)#切換到iframe url1 = driver.execute_script("return video") #獲取video變量值 except: f=open('realurl.txt','a') f.write('\n'+filename+'\n') f.write('異常\n') f.close() vu=url1.replace('&ctype=phone','')#截取成XML網址,hd=3這參數是沒影響的,因此留着 driver.close() #關閉瀏覽器 headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Charset': 'UTF-8,*;q=0.5', 'Accept-Encoding': 'gzip,deflate,sdch', 'Accept-Language': 'en-US,en;q=0.8', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0', } text=requests.get(vu,headers=headers) pattern=re.compile('http://[\w|/|\.|&|?|=|,|%|:]+')#匹配視頻URL的正則表達式 url=pattern.findall(text.text)#獲取一集中全部視頻URL #把URL寫進文本 f=open('realurl.txt','a') f.write('\n'+filename+'\n') f.write('\n'.join(url)) f.close() if __name__=='__main__': f=open('dm530.txt','r') for line in f: v=line.strip().split('\t') url=v[0] filename=v[1] t=threading.Thread(target=getvideo,args=(url,filename)) t.start() t.join() #t線程退出後再執行下一步 time.sleep(4) f.close() print('end')
dm530文件經過網頁源代碼製做而成的,以下圖所示:
最後獲取出來的結果realurl.txt(由於有些集數該網站也沒法播放,因此也沒法獲取到),以下圖:瀏覽器