为了账号安全,请及时绑定邮箱和手机立即绑定

python 分析Google音乐下载地址(一)

标签:
Python


Google音乐做的不错,不过可能由于家里网络的的原因,经常听着听着就不动了,就想着下到本地听,不知道他怎么做的,在Internet临时文件夹里看不到音乐的临时文件,从网上只找到一个下载的工具是用PYTHON做的,不过不合我的要求,于是决定自己写一个。

 我比较喜欢听Google整理的专辑,所以就从这里开始了,比如这个页面(http://www.google.cn/music/topiclistingq=top100_north_south_line&cat=song)查看他的源码,发现音乐下载页面的地址是下面红字的部分(<a href="javascript:void(0)" title="下载" oncontextmenu="return false;"onclick="window.open(&quot;/music/url?q\x3dhttp%3A%2F%2Fg.top100.cn%2F12174704%2Fhtml%2Fdownload.html%3Fid%3DS518edb7fd08fbd08\x26resnum\x3d50\x26ct\x3ddl\x26cad\x3dtopic\x26cd\x3d1\x26ei\x3dQrKlSoj5OKewsgKB9PSgAQ&quot;,&#39;&#39;, &quot;resizable\x3d0, status\x3d0, width\x3d750, height\x3d360&quot;);return false;">),所以需要把这一部分提取出来就可以了,自然就想到了用正则表达式,以前没用过,现学现用吧, 看了网上一个30分钟的教程,写了一个正则表达式“(?<=下载.*\/music\/url\?q\\x3d).*(?=\\x26resnum)” ,放到测试工具里能成,但是那个教程讲的是C#的正则表达式,当时机器上没安.net,只能用PYTHON,不过python好像不支持向前预匹配,这个表达式不能用,从网上找了好长时间也没有找到解决的办法,只能用比较的笨的办法了。

  我的思路是这样的,先把‘下载" oncontextmenu="return false;" onclick="window.open(&quot;/music/url?q\x3dhttp%3A%2F%2Fg.top100.cn%2F12174704%2Fhtml%2Fdownload.html%3Fid%3DS518edb7fd08fbd08’这一部分用正则表达式匹配出来,然后再把正确的地址“http%3A%2F%2Fg.top100.cn%2F12174704%2Fhtml%2Fdownload.html%3Fid%3DS518edb7fd08fbd08’”匹配出来,但是匹配的时候又出现了问题,最上面的蓝色部分,我去不掉(python我也不会,也是现学现用),最后匹配出来的是“下载" oncontextmenu="return false;" onclick="window.open(&quot;/music/url?q\x3dhttp%3A%2F%2Fg.top100.cn%2F12174704%2Fhtml%2Fdownload.html%3Fid%3DS518edb7fd08fbd08\x26resnum”好在蓝色部分固定长度,我用[ :-10]把它截去了,最后用正则“http.*”把正确的地址匹配出来。思路弄清楚了就开始写代码,写起来没有想像得那么简单,由于对python一点也不懂,出现了几个不太好弄的问题,开始我用html=urllib.urlopen(“http://www.google.cn/music/topiclisting?q=top100_north_south_line&cat=song”).read()把网页源码读出来,直接匹配html结果一个也出不来,我也不知道什么原因,可以是行太多(我只做了单选的匹配),于是我又把html写到了文件里再一行一行的处理,不过读文件的时候又出来了中文的问题,需要转换编码,从网上找了不少代码没有解决,最后终于找到一个函数,呵呵

def mdcode( str ):

    for c in ( 'utf-8','gbk', 'gb2312'):   

        try:

            return str.decode(c).encode( 'gbk' )

        except:

            pass

    return 'unknown'

         html的源码好像不只有一种编码,转的时候总是转了一部分就报错,走不下去了,用了这个函数就解决了,这样得出来的地址是“http%3A%2F%2Fg.top100.cn%2F12174704%2Fhtml%2Fdownload.html%3Fid%3DS518edb7fd08fbd08”还不能用,需要url编码转换,用urllib.unquote()就行了,最后得出来的地址是

http://g.top100.cn/12174704/html/download.html?id=S518edb7fd08fbd08

当然这个地址不是音乐的下载地址,只是下载页面的地址,还得分析那个页面才能得到真正的下载的地址,当我用urllib.urlopen().read()下载这个地址的时候,下到的不是真正下载页面的源码,可是把这个地址放到浏览器里就成下载页面,可能中间Google做的别的处理吧,这个今天还没有解决,留到下一篇文章里面,下面是现在的全部的代码,刚刚开始学python,写的不好,还希望大家看完了给出意见,谢谢。如果您知道怎样一步用正则表达式把地址匹配出来,还希望您能在下面留言,我想了几天也没弄出来。您可以给我发邮件mistral1986@gmail.com。

 

# coding=utf-8 

import urllib 

import re 

import sys 

def mdcode( str ): 

        for c in ( 'utf-8','gbk', 'gb2312'):         

                try: 

                        return str.decode(c).encode( 'gbk' ) 

                except: 

                        pass    

        return 'unknown' 

    

url = 'http://www.google.cn/music/topiclisting?q=top100_north_south_line&cat=song'    

filename='c:\\tmp\\url.txt' 

wname='c:\\tmp\\out.txt' 

regx='下载.*window.*http.*\\\\x26resnum'#\x26resnum很奇怪,明明看到的是一个‘\’可是匹配不出来,好像是有两个‘\\’ 

reg='http.*' 

list =[] 

result=[] 

html=urllib.urlopen(url).read(); #下载网页 

file=open(filename,'w') 

file.write(html) 

file.close() 

file=open(filename,'r') 

lines=file.readlines() 

reobj=re.compile(regx) 

reo=re.compile(reg) 

for line in lines: 

  for match in reobj.finditer(line): 

    list.append(urllib.unquote(mdcode(match.group())))  #匹配地址,并转码 

for s in list: 

  result.append(s[:-10]) #截去\x26resnum部分 

    

list=[] 

for r in result: 

  for match in reo.finditer(r): 

    list.append(match.group())    #匹配最后地址 

     

file=open(wname,'w') 

for r in list: 

  file.write(r+"\n") 

file.close() 

©著作权归作者所有:来自51CTO博客作者redface999的原创作品,如需转载,请注明出处,否则将追究法律责任

pythonGoogle音乐Google音乐下载Python


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消