• 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("	var 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_[dw]+=(.+?);', script_text).group(1)
            # 用正则表达式定位到下载链接的运算式
            generate_addr = re.sub(r'/*.+?*/', '', generate_addr) #去混淆用注释语句
            return eval(generate_addr) #eval只能计算表达式的值

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


    更新:目前网站增加了一步验证,即需在最后一步用真实地址请求时带上一个Referer头部,这个referer的值即为地址X的分段base64编码拼接,地址X在视频页的源代码里,名为linkProxyUrl,具体分析方法同上文,不再赘述。

  • 相关阅读:
    Java 编程下的并发线程之间的同步代码块死锁
    Java 编程下的同步代码块
    Android 编程下两种方式注册广播的区别
    Java 编程下泛型的内部原理
    Android 编程下使用 Google 的 Gson 解析 Json
    c# 调用音库开发英语单词记忆本
    在.Net中实现RichClient+Restful+JPA架构探索实现
    Extjs 常用正则式
    企业内IT部门的一些问题总结
    WinServer2003部署VS2010的水晶报表
  • 原文地址:https://www.cnblogs.com/qjfoidnh/p/12310227.html
Copyright © 2020-2023  润新知