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只能计算表达式的值

至此便得到了视频真正的下载地址。

猜你喜欢

转载自www.cnblogs.com/qjfoidnh/p/12310227.html