- 论坛徽章:
- 0
|
本帖最后由 斯文牛氓 于 2013-09-25 18:30 编辑
baidu music
NAME
最近很无聊,前几天写了个模拟百度登录和下载mp3音乐的代码,模块是用的Mojo::UserAgent,下载的时 候之前开了AnyEvent,但是下的太快,百度会有屏蔽,想换ip useragent嫌太麻烦,就串行下 着下着吧,程序的参数是feed,输入百度音乐的一个页面即可,例如张学友的一个歌单是:- [url]http://music.baidu.com/artist/2507[/url]
复制代码 那么你就可以运行:- perl baidu.pl [url]http://music.baidu.com/artist/2507[/url]
复制代码 之后就可以把这个页面的所有码率的歌曲下载出来了,下载路径我写死了’/tmp’,懒的改了, 代码是可以直接运行的,帐号是我的测试帐号,如果你有vip,应该可以下载高品质的mp3, 我这里只能下载一般品质的,但是如果是百度网盘的下载这个程序干不了,貌似百度网盘是 temppath,好了不废话,上代码:- use Mojo::UserAgent;
- use 5.010;
- use Mojo::UserAgent::CookieJar;
- use YAML 'Dump';
- use Encode qw(decode encode decode_utf8 encode_utf8);
- use Mojo::IOLoop;
- use File::Spec;
- use File::Basename;
- my $feed = shift;
- my $ua = Mojo::UserAgent->new;
- $ua->name(
- 'Mozilla/5.0 (Macintosh; '.
- 'Intel Mac OS X 10_8_5) AppleWebKit/537.36 '.
- '(KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36'
- );
- # first get baidu index,get first cookie
- say $ua->get('http://www.baidu.com/')->res->code;
- =pod
- var bdPass=bdPass||{};
- bdPass.api=bdPass.api||{};
- bdPass.api.params=bdPass.api.params||{};
- bdPass.api.params.login_token='0be08e1d5fa566d2562715a4083ece70';
- =cut
- my ($token) = $ua->get(
- 'http://passport.baidu.com/v2/api/?getapi&class=login&tpl=mn&tangram=true')
- ->res->body =~ m{login_token\s*=\s*'(.+?)'}six;
- say "token => $token";
- my $staticpage = "http://www.baidu.com/cache/user/html/jump.html";
- my $login_url = "http://passport.baidu.com/v2/api/?login";
- my $user = '492003149@qq.com';
- my $password = 'qq123456';
- my $post_form = {
- charset => 'utf-8',
- token => $token,
- isPhone => "false",
- index => "0",
- staticpage => $staticpage,
- logintype => "1",
- 'tpl' => "mn",
- 'callback' => "parent.bdPass.api.login._postCallback",
- 'username' => $user,
- 'password' => $password,
- 'mem_pass' => "on",
- };
- # cookies must contain 'BDUSS', 'PTOKEN', 'STOKEN', 'SAVEUSERID'
- my $tx = $ua->post( $login_url => form => $post_form );
- if ( $tx->success ) {
- say "get cookie as :";
- say Dump $tx->res->cookies;
- }
- # now,let's go to validate this cookie,get music.baidu and parse the mp3
- # download address,if you do not login,you can't download the high rate file
- # but take the cookie will be ok!
- my @songs = ();
- my $base_url = "http://music.baidu.com";
- # find every song's mp3 and album name,title
- =pod
- <span class="song-title " style="width: 185px;">
- <a href="/song/7317902" title="相思风雨中"> 相思风雨中 </a> <a title="歌曲MV" target="_blank" href="/mv/7317902" class="mv-icon"></a>
- </span>
- <span class="album-title" style="width: 130px;"> <a href="/album/7311811" title="广东经典101">《广东经典101》</a> </span>
- =cut
- for my $e (
- $ua->get($feed)->res->dom->charset('UTF-8')->find('div.song-item')->each )
- {
- my $node = $e->find('span.[class="song-title "] > a')->first;
- my ( $href, $song_id ) = $node->{href} =~ m/(.*?(\d+))/;
- next unless $song_id;
- my $song_url = $base_url . $href;
- push @songs, {
- link => $song_url,
- name => $node->{title},
- # [url]http://music.baidu.com/song/265898/download?__o=%2Fsong%2F265898[/url]
- download_urls =>
- fetch_mp3_download( $song_url . "/download?__o=/song/$song_id" ),
- };
- }
- download_mp3( \@songs, '/tmp' );
- say Dump( \@songs );
- sub download_mp3 {
- my ( $download_info, $path ) = @_;
- for my $s (@$download_info) {
- for my $d ( @{ $s->{download_urls} } ) {
- my $abs_path = File::Spec->catfile( $path, $s->{name} );
- my $file = File::Spec->catfile( $abs_path,
- $d->{rate} . "_" . $s->{name} . "mp3" );
- if ( not -d $abs_path ) {
- mkdir $abs_path;
- }
- my $tx = $ua->get( $d->{download_url} );
- $tx->res->content->asset->move_to($file);
- $d->{downloaded_mp3} = $file if -e $file;
- }
- }
- }
- sub fetch_mp3_download {
- my ($url) = @_;
- my $tx = $ua->get($url);
- my @downloads;
- if ( $tx->success ) {
- for my $e ( $tx->res->dom->find('a')
- ->grep( sub { index( $_->{href}, 'mp3' ) != -1 } )->each )
- {
- push @downloads, {
- rate => $e->{id} . "k",
- download_url => sub { my ($l) = $e->{href} =~ m{link=(.*)}six }
- ->(),
- };
- }
- }
- else {
- say "got download box failed";
- }
- return \@downloads;
- }
复制代码 运行结果:
- - download_urls:
- - download_url: [url]http://zhangmenshiting.baidu.com/data2/music/7344375/732039850400128.mp3?xcode=cd330a33e570d76d254c2deeb463dd6cf424689cd863f193[/url]
- downloaded_mp3: /tmp/味道/128k_味道mp3
- rate: 128k
- - download_url: [url]http://zhangmenshiting.baidu.com/data2/music/44806384/732039850400256.mp3?xcode=cd330a33e570d76df67218ee4cf8e714bcc3362f19e9add9[/url]
- downloaded_mp3: /tmp/味道/256k_味道mp3
- rate: 256k
- link: [url]http://music.baidu.com/song/7320398[/url]
- name: 味道
- - download_urls:
- - download_url: [url]http://zhangmenshiting.baidu.com/data2/music/2367646/2131180187200128.mp3?xcode=cd330a33e570d76db655cdf35416240e9609f46fadf8ce7c[/url]
- downloaded_mp3: /tmp/她来听我的演唱会/128k_她来听我的演唱会mp3
- rate: 128k
- - download_url: [url]http://zhangmenshiting.baidu.com/data2/music/44805709/2131180187200256.mp3?xcode=cd330a33e570d76df67218ee4cf8e714aaab344d72bdf967[/url]
- downloaded_mp3: /tmp/她来听我的演唱会/256k_她来听我的演唱会mp3
- rate: 256k
- link: [url]http://music.baidu.com/song/2131180[/url]
- name: 她来听我的演唱会
- - download_urls:
- - download_url: [url]http://zhangmenshiting.baidu.com/data2/music/7312444/1028646194400128.mp3?xcode=cd330a33e570d76d21bac3faf65e237dda8fb61a6a1f8c11[/url]
- downloaded_mp3: /tmp/每次都想呼喊你的名字/128k_每次都想呼喊你的名字mp3
- rate: 128k
- - download_url: [url]http://zhangmenshiting.baidu.com/data2/music/44804660/1028646194400256.mp3?xcode=cd330a33e570d76df67218ee4cf8e714e859495a9f88188d[/url]
- downloaded_mp3: /tmp/每次都想呼喊你的名字/256k_每次都想呼喊你的名字mp3
- rate: 256k
复制代码 代码有点搓,不过还是能工作的。最后说一下,Mojo::UserAgent 真的粉好用!!!!
AUTHOR
舌尖上的牛氓
qq 群: perl-china交流群 211685345
社区 : perl-china.com |
|