上一篇博文是我的第一篇技术博客,看的人还不少,给了我一些动力,平时也是看的东西多,但是很少有总结,今年开始写一些自己觉得有意思的东西.

  我觉得网上的一些资料大多是直接给出处理的结果,而不注重分析过程,对我们程序员来说,其过程更重要,工作中碰到的问题是多种多样的,不可能每个碰到的问题都能从网上直接找到答案,我也觉得作为程序员直接去找答案的做法本身有问题.应该提高主动去分析解决问题的能力.下面是对这类问题的一个相对通用的分析方法.

1.URL分析

http://v.qq.com/cover/g/g9jgclyhpp5sp7p.html?vid=g00118pmaso

打开这个url的页面源码,找到下面这些内容:

var COVER_INFO = {
title :”独家首发”,
id :”g9jgclyhpp5sp7p“,
isPrev :false,
pic :”http://i.gtimg.cn/qqlive/img/jpgcache/files/qqvideo/g/g9jgclyhpp5sp7p_h.jpg”,
typeid:22,
videoReName :false,
sourceid:0,
isEurope:false,
useTextVideoList:false,
columnid:0,
hasRecommend:true,
specialTemp:false,
varietyDate:””,
copyright:5
};

在源码中搜索g9jgclyhpp5sp7p字符串,从其出现的位置基本可以判断这个字符串唯一代表了一个合集(或者叫专辑). 不管它有没有用,先大概看一下,把URL中觉得有用的东西过一遍.

腾讯视频播放地址的url有几种模式,上面是其中一种,其它的几种模式对解析其地址没什么太大关系,这里就以这种为例了.这个url中最关键的就是最后面接的一个参数vid(videoID)=g00118pmaso.

2. 抓包

  这里首先要说一点,平时做web应用或者后台接口,要有习惯去抓包,并且对抓到的包进行一些简单的分析,这是一个很好的习惯,有时候会学到一些意想不到的东西.

  最简单的抓包方式就是直接用浏览器自带的工具了,我平时用的chrome,F12 – Network中就有当前页面发送出去的http报文,另外还有个小技巧,因为浏览器会有缓存,按Ctrl+F5刷新页面,就会强制从服务端获取内容而不用缓存,有时候需要这样做,具体的原理可以去看看http协议中的Cache-Control头部. 用浏览器抓包还有个不太方便的地方,当页面跳转时,前面抓的包就没有了,抓的永远是当前页面相关的报文.所以我平时用的比较多的是fiddler,一个免费的抓包工具,非常方便.

  回到正题, 我们从浏览器输入链接http://v.qq.com/cover/g/g9jgclyhpp5sp7p.html?vid=g00118pmaso, 抓到了很多http包,我这里给出一部分的截图

  

标出来的部分请求是关键请求, 我自己在分析的时候,是从下往上分析的,

1)首先找到视频的下载地址

http://101.71.72.2/music.qqvideo.tc.qq.com/g00118pmaso.p309.1.mp4?sdtfrom=v10&type=mp4

&vkey=95C006D54AA7217B859B15732EE04FB88B3986D36E53116ECAF1CFD43EE6615BA6AD5DDDF8CC3D7B

&level=3&platform=1&br=351&fmt=fhd&sp=0

这里继续分析url,g00118pmaso上面讲到了,是vid,但是后面多出了.p309.1. 继续往下看sdtfrom=v10(未知),type=mp4,这个好理解,vkey=95C006D54AA7217B859B15732EE04FB88B3986D36E53116ECAF1CFD43EE6615BA6AD5DDDF8CC3D7B,这个看起来又像是一个比较关键的参数,level=3(后面xml中对应的level),platform=1(平台,web、client、iphone…?暂时也是未知),br=351(bitrate=351?大概是码率的意思,后面xml中的br=351),fmt=fhd(大概意思是format=flvHD?实际上这里是后面id为10309对应的format name),sp=0(后面xml中对应的sp).

这里有一大堆的参数,有很多都是未知,这个时候别慌,整个链接直接下载肯定是可以下载到视频的,现在要做的是,去掉其中一些参数,看是否能下载.

http://101.71.72.2/music.qqvideo.tc.qq.com/g00118pmaso.p309.1.mp4?type=mp4

&vkey=95C006D54AA7217B859B15732EE04FB88B3986D36E53116ECAF1CFD43EE6615BA6AD5DDDF8CC3D7B

&br=351&fmt=fhd最后发现,保留这些参数,能正常下载到视频。所以其它参数暂时先别管。这里有几个关键的地方,vkey从哪里来的?br和fmt从那里获取?vid后面的p309.1哪里来的?还有就是ip地址来源未知。分析到这里,继续往上找到另一个比较关键的请求。

http://vv.video.qq.com/getkey

分析玩上面的视频地址链接的组成,很容易就找到了这个请求,getkey。它是一个post请求,查看其发送的参数format=10309&otype=xml&vt=210&vid=g00118pmaso&ran=0%2E9477521511726081

&charge=0&filename=g00118pmaso%2Ep309%2E1%2Emp4&platform=11

http response中的内容如下:

  1. <?xml version="1.0" encoding="utf-8" standalone="no" ?>
  2. <root><br>360602.1875</br><ct>604800</ct><key>95C006D54AA7217B859B15732EE04FB88B3986D36E53116ECAF1CFD43EE6615BA6AD5DDDF8CC3D7B</key><level>3</level><levelvalid>1</levelvalid><s>o</s><sp>0</sp><sr>0</sr></root>

在这里我们找到了key,同时还发现了和上面链接对应的level和sp两个参数,上面一个链接中的一个参数,不过这个参数也非必要,暂时不管。

URLDecode后为:

format=10309(这里实际上是后面的format id)&otype=xml&vt=210&vid=g00118pmaso

&ran=0.9477521511726081&charge=0&filename=g00118pmaso.p309.1.mp4&platform=11

同样,在代码中试,看那几个参数是必要的,经试验,发现format,type,vid,filename是必要的。

继续网上分析第三个url,http://vv.video.qq.com/getinfo

也是一个POST请求,参数是:

otype=xml&pid=2FAF2F6427123207101EBDA3F1523310A76216BD&

platform=11&vids=g00118pmaso&charge=0&speed=1246&ran=0.8439321480691433

返回的结果如下:

复制代码
  1. <?xml version="1.0" encoding="utf-8" standalone="no" ?>
  2. <root>
  3. <fl>
  4. <cnt>5</cnt>
  5. <fi>
  6. <br>64</br>
  7. <id>1</id>
  8. <name>flv</name>
  9. <sl>0</sl>
  10. </fi>
  11. <fi>
  12. <br>550</br>
  13. <id>10301</id>
  14. <name>shd</name>
  15. <sl>0</sl>
  16. </fi>
  17. <fi>
  18. <br>230</br>
  19. <id>10302</id>
  20. <name>hd</name>
  21. <sl>0</sl>
  22. </fi>
  23. <fi>
  24. <br>64</br>
  25. <id>10303</id>
  26. <name>sd</name>
  27. <sl>0</sl>
  28. </fi>
  29. <fi>
  30. <br>900</br>
  31. <id>10309</id>
  32. <name>fhd</name>
  33. <sl>1</sl>
  34. </fi>
  35. </fl>
  36. <hs>0</hs>
  37. <ls>0</ls>
  38. <preview>276</preview>
  39. <s>o</s>
  40. <tm>1361366724</tm>
  41. <vl>
  42. <cnt>1</cnt>
  43. <vi>
  44. <br>351</br>
  45. <ch>0</ch>
  46. <cl>
  47. <ci>
  48. <cd>276.480011</cd>
  49. <cmd5>beace783957b52f460006604229b57cf</cmd5>
  50. <cs>99699295</cs>
  51. <idx>1</idx>
  52. <keyid>g00118pmaso.10309.1</keyid>
  53. </ci>
  54. <fc>1</fc>
  55. </cl>
  56. <fmd5>4ebecd94d64f46666d4e43826c120b5f</fmd5>
  57. <fn>g00118pmaso.p309.mp4</fn>
  58. <fs>99699378</fs>
  59. <fst>5</fst>
  60. <lnk>g00118pmaso</lnk>
  61. <logo>1</logo>
  62. <pl>
  63. <cnt>2</cnt>
  64. <pd>
  65. <c>10</c>
  66. <cd>2</cd>
  67. <fmt>40001</fmt>
  68. <fn>q1</fn>
  69. <h>45</h>
  70. <r>10</r>
  71. <url>http://video.qpic.cn/video_caps/0/</url>
  72. <w>80</w>
  73. </pd>
  74. <pd>
  75. <c>5</c>
  76. <cd>2</cd>
  77. <fmt>40002</fmt>
  78. <fn>q2</fn>
  79. <h>90</h>
  80. <r>5</r>
  81. <url>http://video.qpic.cn/video_caps/0/</url>
  82. <w>160</w>
  83. </pd>
  84. </pl>
  85. <share>1</share>
  86. <st>2</st>
  87. <td>276.48</td>
  88. <ti>因你而在</ti>
  89. <type>3585</type>
  90. <ul>
  91. <ui>
  92. <dt>2</dt>
  93. <dtc>10</dtc>
  94. <url>http://101.71.72.2/music.qqvideo.tc.qq.com/</url>
  95. <vt>210</vt>
  96. </ui>
  97. <ui>
  98. <dt>2</dt>
  99. <dtc>10</dtc>
  100. <url>http://113.207.98.27/music.qqvideo.tc.qq.com/</url>
  101. <vt>210</vt>
  102. </ui>
  103. <ui>
  104. <dt>2</dt>
  105. <dtc>10</dtc>
  106. <url>http://video.store.qq.com/</url>
  107. <vt>0</vt>
  108. </ui>
  109. </ul>
  110. <vh>1080</vh>
  111. <vid>g00118pmaso</vid>
  112. <videotype>0</videotype>
  113. <vw>1920</vw>
  114. </vi>
  115. </vl>
  116. </root>
复制代码

看到这个后,比较兴奋,想要的东西基本上在这里可以找到了。再回过来分析一下这个请求所带的参数

otype=xml&pid=2FAF2F6427123207101EBDA3F1523310A76216BD

&platform=11&vids=g00118pmaso&charge=0&speed=1246&ran=0.8439321480691433

otype返回格式,pid看起来又像是个比较重要的参数(未知),platform(上面是1,这里又来了个11,不明白),vid和上面一样,charge(应该是付费信息,0表示不付费,来源未知),speed(未知),ran和上面一样应该是个0-1之间的随机数。用httpclient模仿这个请求,令人兴奋的是只需要vids和otype就能返回该xml(不需要再去找pid了)。

再整理一下:

1.先通过http://vv.video.qq.com/getinfo POST请求添加参数otype,vid就能获得上面的xml。

2.根据这个xml中的内容发送http://vv.video.qq.com/getkey POST请求,参数列表为format,type,vid,filename。

其中format的id和name有个对应关系,10309-fhd、10303-sd、10302-hd。这里填写的为id。例如:format=10309

filename由几部分组成g00118pmaso.p309.1.mp4 最前面一部分是vid,如果格式id为10309,则后面加上p309.1,最后是格式mp4。例如我我要下载格式id为10303的视频,那拼出来应该是g00118pmaso.p303.1.mp4。

type为xml,vid为每个视频唯一的id,这里是g00118pmaso

3.根据以上信息拼接视频的真实地址

首先是xml中的地址http://101.71.72.2/music.qqvideo.tc.qq.com

紧跟着拼上filename,这里例如g00118pmaso.p309.1.mp4、g00118pmaso.p303.1.mp4、g00118pmaso.p302.1.mp4、g00118pmaso.p301.1.mp4。注意filename要和vkey一一对应,不能用p309的key和g00118pmaso.p303.1.mp4拼接。

然后就是vkey,根据filename获得的vkey进行拼接。

接着type=mp4,fmt和format id对应,例如10309对应的是fhd。

对于format id为10309的视频,最后拼出来的结果是http://101.71.72.2/music.qqvideo.tc.qq.com/g00118pmaso.p309.1.mp4?type=mp4

&vkey=95C006D54AA7217B859B15732EE04FB88B3986D36E53116ECAF1CFD43EE6615BA6AD5DDDF8CC3D7B&fmt=fhd

注意这里把一些不必要的参数去掉了。

 3. 若通过抓包的方式无法分析出来真实地址,则需要反编译swf,找到拼接视频地址的代码,还原其过程。

腾讯的视频地址分析还算顺利,因为不需要反编译swf,上一篇虾米网真实地址解析运气不错,反编译出来的代码很容易找到了关键部分。在分析youtube的地址时,需要反编译swf,但是用网上的一些免费反编译工具反编译出来的源文件不太全,没找到关键代码。

版权声明:本文为Jere-Jobs原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/jere-jobs/archive/2013/02/21/2921300.html