PornHub在線視頻接口逆向


PornHub的免費視頻登錄后是可以直接下載的,且鏈接就直接放在源代碼里,我們只需要在請求中帶上Cookies即可下載。但收費視頻只支持在線觀看,如果免費用戶要下載到本地,就需要找到在線播放對應的文件鏈接。

打開Chrome調試模式並播放視頻,Network選項卡里顯示視頻是從https://cv.phncdn.com/videos/xxxxxxx的鏈接取到的,在調試工具的Elements窗口里查找到此鏈接位於一個<video>標簽內,但右鍵源代碼里並沒有此標簽,顯然是異步渲染的。

查找"cv."關鍵詞,發現它只在id="player"標簽下的一大段script里出現了,這段script的前十幾行,定義了一個變量,可以讀出描述了一些此視頻的元信息;而后就是超長且無分行的大段定義,這種人為的可讀性障礙一般就意味着里面有干貨。搜索關鍵字(比如720p, 1080p這種分辨率),發現定位到的文本是這樣的:

var quality_1080p=/* + ravbmd0slra75ravbmd0slra75 + */rahttpscra100rahttpscra100 + /* + ra8a47lxizkra10ra8a47lxizkra10 + */ravphncdnra87ravphncdnra87 + /* + ravbmd0slra75ravbmd0slra75 + */racomvideora70racomvideora70 + /* + ra6zdjixveara14ra6zdjixveara14 + */ras202001ra48ras202001ra48 + /* + rarwyc9jryra34rarwyc9jryra34 + */ra29280164ra17ra29280164ra17 + /* + raxxaaxrr2bra23raxxaaxrr2bra23 + 
...中間略
+rajizy4aof8ra97rajizy4aof8ra97 + /* + rahiuxvgjbdra31rahiuxvgjbdra31 + */rait5pb7qvra34rait5pb7qvra34 + /* + ravphncdnra87ravphncdnra87 + */rafrdzfusijra70rafrdzfusijra70 + /* + ravkr6lm0dlra94ravkr6lm0dlra94 + */rapd8628sljra94rapd8628sljra94 + /* + ra8a47lxizkra10ra8a47lxizkra10 + */raqbf2mfoy5ra88raqbf2mfoy5ra88 + /* + rahttpscra100rahttpscra100 + */rac5daiara85rac5daiara85;
View Code

是一個字符串拼接,只是寫了大量注釋來混淆視聽,而涉及到的拼接變量,經查找正好在此段文本之前的內容做了定義,至此有一些js基本功的就可以寫一個下載腳本了。

 

但如果要用Python寫爬蟲怎么辦?execjs和py2js這樣的庫是一個可考慮的選項,但此類庫往往有執行速度慢和環境配置坑多的問題,並且筆者在實際使用過程中,還發現js語句中某些符號會導致此類庫解析拋出異常。事實上Python與JavaScript在某些基礎語法上是很相近的,我們完全可以把js語句轉化為Python語句執行。

def getpornaddr(content: bs4.BeautifulSoup):
    script = content.select_one('#player').script
    if not script: return 'error'
    else:
        script_text = script.text.strip()
        # 根據變量命名特性划定有用的script范圍
        begin = script_text.rindex("\tvar ra")
        end = script_text.index("var quality_")
        valid_zone = script_text[begin:end].replace('var ','').strip() #Python支持末尾分號,所以不需處理,只把var 字樣去掉即可,現在已經是Python的變量定義式了
        exec(valid_zone)
        # exec方法能把字符串當做語句執行,無論在js還是Python里,exec都是一種挺危險的行為,要謹慎使用
        generate_addr = re.search(r'var quality_[\d\w]+=(.+?);', script_text).group(1)
        # 用正則表達式定位到下載鏈接的運算式
        generate_addr = re.sub(r'/\*.+?\*/', '', generate_addr) #去混淆用注釋語句
        return eval(generate_addr) #eval只能計算表達式的值

至此便得到了視頻真正的下載地址。

 


更新:目前網站增加了一步驗證,即需在最后一步用真實地址請求時帶上一個Referer頭部,這個referer的值即為地址X的分段base64編碼拼接,地址X在視頻頁的源代碼里,名為linkProxyUrl,具體分析方法同上文,不再贅述。

 


免責聲明!

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



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