今日头条视频的地址解析下载

以今日头条视频播放页URL http://www.toutiao.com/a6296462662335201793/ 为例,来说说是如何得到视频的真实地址的。

在Chrome浏览器中打开上面的链接,然后审查播放器区域的元素,发现是这样的:

<video id="vjs_video_3_html5_api" class="vjs-tech" preload="auto" autoplay="" src="http://v6.pstatp.com/video/c/c62f4d4320ea43469b490e54240653ab/?Signature=D2cYsGzKaEXraZQnOf72xgJ94%2Bs%3D&Expires=1469172376&KSSAccessKeyId=qh0h9TdcEMrm1VlR2ad/">
<source type="video/mp4" src="http://v6.pstatp.com/video/c/c62f4d4320ea43469b490e54240653ab/?Signature=D2cYsGzKaEXraZQnOf72xgJ94%2Bs%3D&Expires=1469172376&KSSAccessKeyId=qh0h9TdcEMrm1VlR2ad/">
</video>

原来是使用了HTML5的video标签,该标签的src属性值就是视频的真实地址。是不是很简单?如果我们想写个脚本来自动解析视频的真实地址,会发现情况不一样。

说明:以下代码片段均使用Python语言。

import requests
from pyquery import PyQuery as pq

r = requests.get('http://www.toutiao.com/a6296462662335201793/')
d = pq(r.content)
d('video')  # video元素不存在
d('#video') # id是video的元素是存在的

当我们把播放页下载下来,并且尝试提取video元素的时候,发现下载下来的播放页中根本就没有video元素。这说明video元素可能是js脚本动态生成的,该想想其它办法了。

通过观察加载播放页页面时的网络请求,我们发现如下相关的请求:

http://v7.pstatp.com/b97adb57aaa351e485ed69c5e4852211/5791c279/video/c/c62f4d4320ea43469b490e54240653ab/
http://i.snssdk.com/video/urls/v/1/toutiao/mp4/9583cca5fceb4c6b9ca749c214fd1f90?r=18723666135963302&s=3807690062&callback=tt_playerzfndr

其中,第1个请求就是视频真实地址,第2个请求返回的是一个JSON字符串,内容如下:

{
  "code": 0,
  "message": "success",
  "total": 3,
  "data": {
    "status": 10,
    "video_duration": 0,
    "video_id": "9583cca5fceb4c6b9ca749c214fd1f90",
    "user_id": "toutiao",
    "video_list": {
      "video_3": {
        "definition": "720p",
        "vtype": "mp4",
        "main_url": "aHR0cDovL3Y3LnBzdGF0cC5jb20vZmJiZmE2Yjc4ZjM4MThhM2M0OTVhMmRkYjAyOWY5NTAvNTc5\nMWMzODAvdmlkZW8vYy8zNDMwNzcxZjMyNmY0ZDUxOTRiNTYyMzdhNmEyMzFmYy8=\n",
        "vwidth": 720,
        "backup_url_1": "aHR0cDovL3Y2LnBzdGF0cC5jb20vdmlkZW8vYy8zNDMwNzcxZjMyNmY0ZDUxOTRiNTYyMzdhNmEy\nMzFmYy8/U2lnbmF0dXJlPTMwd25YNHVBYzJ1JTJGdSUyRlNvNjhDM010U1VRVW8lM0QmRXhwaXJl\ncz0xNDY5MTc0MTYwJktTU0FjY2Vzc0tleUlkPXFoMGg5VGRjRU1ybTFWbFIyYWQv\n",
        "bitrate": 0,
        "vheight": 576,
        "size": 0
      },
      "video_2": {
        "definition": "480p",
        "vtype": "mp4",
        "main_url": "aHR0cDovL3Y0LnBzdGF0cC5jb20vM2ZiYTI0YzVhYzE1NGVlNmIxMGQ4ZTAyZThhNGQxZDMvNTc5\nMWMzODAvdmlkZW8vYy9jNjJmNGQ0MzIwZWE0MzQ2OWI0OTBlNTQyNDA2NTNhYi8=\n",
        "vwidth": 600,
        "backup_url_1": "aHR0cDovL3Y0LnBzdGF0cC5jb20vM2ZiYTI0YzVhYzE1NGVlNmIxMGQ4ZTAyZThhNGQxZDMvNTc5\nMWMzODAvdmlkZW8vYy9jNjJmNGQ0MzIwZWE0MzQ2OWI0OTBlNTQyNDA2NTNhYi8=\n",
        "bitrate": 0,
        "vheight": 480,
        "size": 0
      },
      "video_1": {
        "definition": "360p",
        "vtype": "mp4",
        "main_url": "aHR0cDovL3Y2LnBzdGF0cC5jb20vdmlkZW8vYy9iODgwZmI1YzM1NjE0NzJlOThlNGU0Y2U5N2My\nYzg5ZS8/U2lnbmF0dXJlPXBlTWhoNFdLcyUyRkNmRW9pYm4wTVNKUU5tR1lnJTNEJkV4cGlyZXM9\nMTQ2OTE3NDE2MCZLU1NBY2Nlc3NLZXlJZD1xaDBoOVRkY0VNcm0xVmxSMmFkLw==\n",
        "vwidth": 450,
        "backup_url_1": "aHR0cDovL3Y3LnBzdGF0cC5jb20vNjFhYTJlN2RlN2YxZTgzNGJiNjg3ZDZmMDZjZGFmNzMvNTc5\nMWMzODAvdmlkZW8vYy9iODgwZmI1YzM1NjE0NzJlOThlNGU0Y2U5N2MyYzg5ZS8=\n",
        "bitrate": 0,
        "vheight": 360,
        "size": 0
      }
    }
  }
}

看看JSON内容,可以看到共有3种清晰度视频,分别是超清、高清和标清。definition表示清晰度,main_url应该就是视频真实地址了。main_url的值看起来就是base64编码后的结果,用base64解码main_url,得到的就是视频真实地址。

import base64
main_url = "aHR0cDovL3Y3LnBzdGF0cC5jb20vZmJiZmE2Yjc4ZjM4MThhM2M0OTVhMmRkYjAyOWY5NTAvNTc5\nMWMzODAvdmlkZW8vYy8zNDMwNzcxZjMyNmY0ZDUxOTRiNTYyMzdhNmEyMzFmYy8=\n"
base64.standard_b64decode(main_url) 
# output: http://v7.pstatp.com/fbbfa6b78f3818a3c495a2ddb029f950/5791c380/video/c/3430771f326f4d5194b56237a6a231fc/

那么接下来的问题就是探究上面的第2个请求 http://i.snssdk.com/video/urls/v/1/toutiao/mp4/9583cca5fceb4c6b9ca749c214fd1f90?r=18723666135963302&s=3807690062&callback=tt_playerzfndr 是如何构造的。

在用Chrome的开发者工具监视网络请求的时候可以看到该请求是js脚本发出的,该js脚本是 http://s3.pstatp.com/tt_player/player/tt2-player.js?r=customer1
把该js下载下来,prettify一下,使用你最爱的编辑器看看该js到底做了些什么。

通过研究该js脚本,发现请求http://i.snssdk.com/video/urls/v/1/toutiao/mp4/9583cca5fceb4c6b9ca749c214fd1f90?r=18723666135963302&s=3807690062&callback=tt_playerzfndr 中的一些参数的含义如下:

  • 9583cca5fceb4c6b9ca749c214fd1f90:这是视频的唯一ID
  • 18723666135963302:这是一个随机数
  • 3807690062:这是CRC32校验值无符号右移0位

视频的唯一ID可以在播放页HTML源码中找到,即id为video的元素的tt-videoid属性值。

import requests
from pyquery import PyQuery as pq

r = requests.get('http://www.toutiao.com/a6296462662335201793/')
d = pq(r.content)
vid = d('#video').attr('tt-videoid')

参数r的构造如下:

import random

r = str(random.random())[2:]

参数s的构造如下:

import urlparse

def right_shift(val, n):
    return val >> n if val >= 0 else (val + 0x100000000) >> n

url = 'http://i.snssdk.com/video/urls/v/1/toutiao/mp4/%s' % vid
n = urlparse.urlparse(url).path + '?r=' + r
c = binascii.crc32(n)
s = right_shift(c, 0)

参数callback就不管了吧。到此,获取JSON内容就简单了:

r = requests.get(url + '?r=%s&s=%s' % (r, s))
print r.json()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容