
一直以来都用豆瓣电台听歌,随着歌龄的增加,小豆瓣越来越熟知我们的喜好了,在私人电台里面总是会挑选出来我们喜欢的歌曲呢。这里我有一个永久的财富,就是加心歌曲了,每次听歌总是会把自己喜欢的歌曲加上个红心,长期以来也积累了不少。杞人忧天的精神总是驱动我,万一有一天不能联网了,肿么办?下载到本地才是正解。 GG
一下看了几个教程
:
http://www.isnowfy.com/download-doubanfm-songs/ 这个是用一个Python
弄的,有一点就不怎么好的就是需要你获取登陆后的
cookies
的有没有?
http://www.douban.com/note/187105892/ 这里收集了很多的了。而且分析了各个的利弊吧。 前段时间,诸于换手机之类。用上了小机器人,而且惊喜的发现有一款应用叫豆瓣电台,而且很惊喜的发现里面有“红心赫兹”!不过只能同步
100M
的数据,这个对于我们来说远远不够。要就要全部下载下来的好。这里既然是通过网络,就应该可以通过某种程度获得数据的。手机连接
WiFi
,不好获得无线路由器上的数据。但是我利用
Win7
的某个功能,将自己的无线网卡改造成无线路由器(
参考一,
参考二),然后通过
WireShark
监控无线网卡上的包,那么应该是一览无余了(这里主要讨论获取豆瓣的加心歌曲,关于
WireShark
的使用,可以参考
这里)。 如果你想一步一步做下去,你可能需要:有一定的编码基础,了解一些工具的使用如wireshark;如果你仅仅想获得那些歌曲,就直接访问这个地址:
http://blog.satikey.com/tools/douban,代码在最底下,PHP版的。 首先,搭建好环境(这里是说把Win7无线网卡改造成wifi),用
Wireshark
监控无线路由器,手机上(这里是
Android
)登陆豆瓣
FM
(先清空掉数据吧),然后你在豆瓣
FM
里登陆,切换到红心频道。这里注意查找
Wireshark
里面捕获到数据。

这里提取到关键的数据,然后我们Follow TCP Stream

请求的地址是:
http://www.douban.com/j/app/radio/liked_songs?count=10&token=7sasda19f525&exclude=&version=606&client=s%3Amobile%7Cy%3Aandroid+2.3.5%7Cf%3A606%7Cm%3ADouban%7Cd%3A-1629744272%7Ce%3Ahkcsl_cht_htc_desire_s&app_name=radio_android&from=android_606_Douban&user_id=153edsa182&expire=1351265604&formats=aac
修改
count
值到
200

于是我们可以看到,这个是可以获得值的,而且获得更多的响应内容。 而当修改了
token
和
user_id
,返回的内容:
{"err":"invalid_token", "r":1}
下面的问题就很清楚了,我们需要怎么获得
token
和
user_id. 而在
wireshark
里面获取的包中,并没有相关的内容(这个我找了好久),按照经验来说获取令牌和用户
ID
应该是在登陆的过程产生的,当我们重复登陆过程的时候,发现:

Follow tcp stream
看到的:

通过
https
把内容给加密了,这个就是防止我们这样抓取数据,以便截取密码之流,因此有时候还是“
莫蹭网”。我们不能因此而困在这里,手上有
apk
,可以那么个一下。具体的流程请
GG
。这里只是提供一个结果。 将以下数据:
"email=<
你的邮箱
>&password=<
你的密码
>&app_name=radio_android&version=606&client=s%3Amobile%7Cy%3Aandroid+2.3.5%7Cf%3A606%7Cm%3ADouban%7Cd%3A-1629744272%7Ce%3Ahkcsl_cht_htc_desire_s ";
通过
post
方式到:
https://www.douban.com/j/app/login
返回的内容于是是:

看吧,于是就获得了
user_id
和
token
还有
expire
。 下面是一个封装好的页面:
http://blog.satikey.com/tools/douban 然后是实现的代码:
<?php
/**
*
* @category
* @package
* @author Lei<lei_d@qq.com>
* @listence Apache Listens,Version 2.0
* @version 2012-04-30
*/
$email=isset($_GET['email'])?$_GET['email']:'';
$password=isset($_GET['pwd'])?$_GET['pwd']:'';
$count=isset($_GET['count'])?$_GET['count']:'10';
if(!preg_match('/^[\w\-\.]+@[\w\-\.]+(\.\w+)+$/',$email)){
return;
}
$login_info=login($email,$password);
$liked_list= get_liked($login_info,$count);
//var_dump($liked_list);
if($liked_list->r!=0){
echo "wrong";
return;
}
$urls='';
$cmd='';
foreach($liked_list->songs as $songs){
$urls.=$songs->url.'<br/>';
$title=$songs->title;
//文件名
$offset1=strrpos($songs->url,'/')+1;
$tempName=substr($songs->url,$offset1);
//扩展名
$offset2=strrpos($songs->url,'.');
$ext=substr($songs->url,$offset2);
//生成cmd
$cmd.='ren '.$tempName.' "'.$title.$ext.'"<br/>' ;
}
echo $urls;
echo "<hr/>";
echo $cmd;
return;
function login($email,$password)
{
// if(s.contains("@"))
// s2 = "email";
// else
// s2 = "username";
$PostData = "email=".$email."&password=".$password."&app_name=radio_android&version=606&client=s%3Amobile%7Cy%3Aandroid+2.3.5%7Cf%3A606%7Cm%3ADouban%7Cd%3A-1629744272%7Ce%3Ahkcsl_cht_htc_desire_s";
$ch = curl_init("https://www.douban.com/j/app/login");
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_USERAGENT,'Android-2.3.5');
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_CAINFO,'mozilla.pem'); /* fixed! */
//post
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $PostData);
$result = curl_exec($ch);
curl_close($ch);
$jsonObj=json_decode($result);
return $jsonObj;
}
function get_liked($login_info=array(),$count){
$url='http://www.douban.com/j/app/radio/liked_songs?count='.$count.'&token='.$login_info->token.
'&exclude=&version=606&client=s%3Amobile%7Cy%3Aandroid+2.3.5%7Cf%3A606%7Cm%3ADouban%7Cd%3A-1629744272%7Ce%3Ahkcsl_cht_htc_desire_s&app_name=radio_android&from=android_606_Douban'.
'&user_id='.$login_info->user_id.
'&expire='.$login_info->expire.'&formats=aac';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_USERAGENT,'Android-2.3.5');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$curlResponse = curl_exec($ch);
$curlErrno = curl_errno($ch);
if ($curlErrno) {
$curlError = curl_error($ch);
}
curl_close($ch);
$jsonObj=json_decode($curlResponse);
return $jsonObj;
}
via:http://blog.satikey.com/?p=194