4.5.1 VIP視頻爬取


4.5.1 VIP視頻爬取

​ 冬夜微醺,挑燈回嘆,巍哥無心睡眠,突然想看片。於是巍哥上網搜索python,學習了起來。

一、基本概念

爬蟲是什么

爬蟲是指請求網站並獲取數據的自動化程序。谷歌的搜索引擎爬蟲,隔幾天對全網的網頁爬取一遍,供大家查閱,這應是善意爬蟲。但12306搶票軟件爬蟲,為了私欲無節制地訪問網站,這就是惡意爬蟲。技術很單純,哲學很復雜。

爬蟲做什么

我們訪問網站:瀏覽器提交請求->下載網頁代碼->解析成頁面

爬蟲訪問網站:模擬瀏覽器發送請求->獲取網頁代碼提取有用數據->存於數據庫或文件中

訪問網站的HTTP連接消息報文有Request請求和Response響應兩種。用戶發送Request后瀏覽器接收到網站Response后,會解析其內容來顯示給用戶。而爬蟲程序則是模擬瀏覽器發送請求接收網站Response后,提取其中有用數據。

反爬是什么

貓和老鼠已可以和諧共處了,矛與盾雖惺惺相惜卻很難真正的親近。爬-反爬-反反爬-反反反爬……對反爬手段建立初步概念,小白在學習實踐中可以多些思考的方向避免入坑。

  • 判斷請求頭來進行反爬

​ 這是網站早期的反爬方式:User-Agent/referrer/cookie

​ 措施:請求頭里面添加對應的參數(復制瀏覽器里面的數據)

  • 根據用戶行為來進行反爬

    • 請求頻率過高,服務器設置規定時間之內的請求閾值

      措施:降低請求頻率或者使用代理(IP代理)

    • 網頁中設置一些陷阱(正常用戶訪問不到但是爬蟲可以訪問到)

      措施:分析網頁,避開這些特殊陷阱

    • 請求間隔太短,返回相同的數據

​ 措施:增加請求間隔

  • js加密

    常見反爬方式,文中獲取視頻下載地址時網站便將時間信息做了js加密附值給參數。

    • 參數加密
      服務器響應給瀏覽器的js文件,動態生成一些加密參數,瀏覽器會根據js的計算得到這些參數。如果請求中沒有這些參數,那么服務器就認為請求無效。

    措施:研究JS,找到生成參數的算法模擬實現。或使用execjsjs代碼提取到py文件中執行。

    • Cookie加密

      瀏覽器運行網站JS生成一個(或多個)cookie再帶着這個cookie做二次請求。服務器那邊收到這個cookie就認為你的訪問是通過瀏覽器過來的合法訪問。

      措施:研究JS,找到生成Cookie的算法模擬實現(把Chrome瀏覽器保存的該網站的cookie刪除后F12觀察)

    • ajax請求參數加密

      抓某個網頁里面的數據,發現網頁源代碼里面沒有我們要的數據,那些數據往往是ajax請求得到的。

      措施: 通過debug JS來找到對應的JS加密算法。F12 “XHR/fetch Breakpoints”、 Selenium+PhantomJS

    • JS反調試(反debug)

      打開F12時,會暫停在一個“debugger”代碼行,無論怎樣都跳不出去。這個“debugger”讓我們無法調試JS。但是關掉F12窗口,網頁就正常加載了。

      措施:在這個函數調用的地方打個“Breakpoint”。刷新頁面,在Console里面重新定義它為空,繼續運行就可以跳過該陷阱。

    • JS發送鼠標點擊事件

      從瀏覽器可以打開正常的頁面,而在requests里面卻被要求輸入驗證碼或重定向其它網頁。F12觀察,每點擊頁面的的鏈接,它都會做一個“cl.gif”的請求。它請求時發送的參數非常多,如包含了被點擊的鏈接等等。因為requests沒有鼠標事件響應就沒有訪問cl.gif的過程就直接訪問鏈接,服務器就拒絕服務。

      措施:訪問鏈接前先訪問一下cl.gif,帶上所需參數。

  • 字體加密

    網站采用了自定義的字體文件,在瀏覽器上正常顯示,但是爬蟲抓取下來的數據是亂碼

  • 登錄驗證碼
    驗證碼登陸才能訪問其網站,從最開始使用簡單驗證碼,識別數字,到更復雜的驗證碼如:內容驗證碼、滑動驗證碼、圖片拼接驗證碼等等。

    措施:一種方法是通過第三方平台接口,完成驗證碼的驗證。

  • 常用加密算法、編碼

    MD5、ASE、RSA、base64

二、視頻爬取

​ 各大視頻網站,VIP視頻一般可以試看6分鍾。所以網絡上就出現了大量的視頻解析網站,在這個灰色地帶,應該是白嫖吸引流量通過廣告謀利。其原理就是調用第三方「視頻解析接口」實現的,源頭估計是一些有VIP賬號的在后台解析視頻然后分享。隨着版權意識、版權管理的加強,以及技術的更新迭代,這類「視頻解析接口」也大量的失效了。

視頻觀看

打開如愛奇藝,搜索《肖申克的救贖》,網址:https://www.iqiyi.com/v_19rra0h3wg.html

借助第三方視頻解析接口,觀看只需要三行代碼即可實現:

import webbrowser
url='https://okjx.cc/?url=https://www.iqiyi.com/v_19rra0h3wg.html' 
webbrowser.open(url)                     

文中使用的解析接口:

# 視頻接口時效不定,找了幾個接口。線路二可以查看劇集,但有廣告
self.lines = {
    "Line-1": "https://okjx.cc/?url={}",
    "Line-2": "https://z1.m1907.cn/?jx={}",
    "Line-3": "https://jx.618g.com/?url={}",
    "Line-4": "http://www.sfsft.com/admin.php?url={}",
}

視頻下載

​ 付費內容,網站肯定不會想讓輕易得到。通過解析接口可以觀看,按道理也就應該能拿到視頻實際地址。視頻下載,一般而言,無非兩種情況:

​ 一種,鏈接明確是以 mp4、mkv、rmvb 這類視頻格式后綴為結尾的鏈接,這種下載很簡單,跟圖片下載方法一樣,就是視頻文件要比圖片大而已。

​ 另一種,鏈接是以 m3u8 這類分段視頻后綴結尾的鏈接,視頻都是分段存儲的。觀看視頻,其實是在加載一個個 ts 視頻片段,一個片段是幾秒鍾的視頻。下載視頻就是將 ts 視頻片段組合成最終視頻。m3u8 這種格式的視頻,就是由一個個 ts 視頻片段組成的。所以下載的關鍵是要獲取m3u8文件的地址。

拿到了關鍵的m3u8文件,多線程加快下載速度,然后用FFmpeg拼接ts文件為一個mp4文件。FFmpeg,它的中文名叫多媒體視頻處理工具。FFmpeg 有非常強大的功能包括視頻采集、視頻格式轉換、視頻抓圖、給視頻加水印等功能。這種 ts 視頻片段合成,格式轉換問題,交給 FFmpeg 就好了。

  1. Windows下的ffmpeg下載安裝
    官方下載地址:https://ffmpeg.org/download.html
    安裝好記得將安裝路徑添加到系統環境變量中

  2. 在Python中使用ffmpy
    pip install ffmpy3

    導入模塊后, 修改ffmpy3.py文件的__init__中的executable為ffmpeg可執行文件的路徑 :

    def __init__(self, executable='D:\\anaconda3\\ffmpeg', global_options=None, inputs=None, outputs=None):
    (例中,把ffmpeg.exe,ffplay.exe,ffprobe.exe三個執行文件拷到了Python安裝目錄)

確認m3u8文件地址

打開瀏覽器Chrome方便使用開發者工具F12,使用線路1(快速且無廣告),輸入網址接口觀看視頻地址: https://okjx.cc/?url=https://www.iqiyi.com/v_19rra0h3wg.html ,視頻播放的同時,F12觀察:

image-20220111172934387

在出現大量ts文件之前,找了一陣子也沒找到包含m3u8文件的請求與應答。

於是換了線路2進行嘗試:https://z1.m1907.cn/?jx=https://www.iqiyi.com/v_19rra0h3wg.html

開心地發現很容易就看到第4條請求中就包含着m3u8的應答:

image-20220111173009541

請求頭內容為:

image-20220111173024806

請求的參數為:可見有z, jx, sqig, g , 4個參數

image-20220111173037750

應答內容為:

image-20220111173049048

至此,順利地達成所願:

https://a1.m1907.cn/api/v/?z=631b5f669923a20dae94bf2c5b7bd50e&jx=https://www.iqiyi.com/v_19rra0h3wg.html&s1ig=11401&g=vod.bun,vod2.bd,cnc2.88,cdn.605,c1.moni,cdn7.in,sod.bun,new.isk

可知jx=https://www.iqiyi.com/v_19rra0h3wg.html 中將地址更改為想看視頻的鏈接,就可以得到視頻的m3u8文件供下載。

可惜高興了幾個小時,過了0:00,發現這樣請求失效了。重新播放獲取地址對比發現:

https://a1.m1907.cn/api/v/?z=5d855143e6fd5d1a252ac6c34b2b7e0f&jx=https://www.iqiyi.com/v_19rra0h3wg.html&s1ig=11401&g=vod.bun,vod2.bd,cnc2.88,cdn.605,c1.moni,cdn7.in,sod.bun,new.isk

問題便出在參數z=5d855143e6fd5d1a252ac6c34b2b7e0f上,它變了。可見這個參數經過了加密且和時間有關。那么請求中的z是怎么得來的呢。如前圖所示,在該請求之前,網站還有2條請求像是js文件。嘗試搜索z=

image-20220111173335776

可見請求之前的兩個js文件都有z的出現。那么,繼續到js文件中找到z的實現:

 case 33:
     c = new Date,
     l = c.getTime(),
     u = 6e4 * c.getTimezoneOffset(),
     d = l + u + 36e5 * 8,
     m = new Date(d),
     p = (p = m).getDate() + 9 + 9 ^ 10,
     p = (p = St()(String(p))).substring(0, 10),
     p = St()(p),
     b = m.getDay() + 11397,
     v = "//a1.m1907.cn/api/v/?z=".concat(p, "&jx=").concat(o),
     v += "&s1ig=".concat(b),
     (g = fe.getAll()) && (v += "&g=".concat(g.join(","))),
     o || (v = "//a1.m1907.cn/api/v/"), 

找到了js代碼中參數z的實現,但打斷點跟蹤那個St( )怎么定義卻迷失了方向,到后來沒信心將那些密密麻麻的實現弄過來是否值得花時間。😦 在要放棄時發現:5d855143e6fd5d1a252ac6c34b2b7e0f,這個32數字很像MD5算法的輸出。於是不甘心地用MD5去試了一下,居然成功了。(希望等以后能力提升了再返回去把這個問題搞清楚) 😃

模擬用python實現:

''' 模擬網站JS中加密:
    request中的query string parameters:
        "z": "5d855143e6fd5d1a252ac6c34b2b7e0f",    
        "jx": "{}"
        "s1ig": "11399",                       
    
    js文件的定義:
    c = new Date,
    l = c.getTime(),
    u = 6e4 * c.getTimezoneOffset(),
    d = l + u + 36e5 * 8,
    m = new Date(d),
    p = (p = m).getDate() + 9 + 9 ^ 10,
    p = (p = St()(String(p))).substring(0, 10),
    p = St()(p),
    b = m.getDay() + 11397,
    v = "//a1.m1907.cn/api/v/?z=".concat(p, "&jx=").concat(o),
    v += "&s1ig=".concat(b),
'''
def MD5p() :
    lt = datetime.datetime.now()
    ut = datetime.datetime.utcnow()
    o = ((ut.day-lt.day)*24+ut.hour-lt.hour)*60
    #o = (ut.hour-lt.hour)*60

    l = int(time.time()*1000)
    u = int(6e4 * o)            
    d = int(l + u + 36e5 * 8)
    m = time.strptime(time.ctime(d/1000)).tm_mday
    p = str(m+ 9 + 9^10) 
    b = lt.weekday()+1 + 11397

    p=md5(p.encode()).hexdigest()
    p=md5(p[0:10].encode()).hexdigest()

    return p, b

關鍵參數z,s1ig便搞定了。剩下的就容易多了。 :)

拿到了關鍵的m3u8文件,多線程下載,用FFmpeg拼接ts文件為一個mp4文件。

至此,巍哥點燃一支煙,長吁一口氣。

代碼實現

附界面顯示:

image-20220111174337430 image-20220111174415166


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM