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

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 ,写的不好,还希望大家看完了给出意见,谢谢。如果您知道怎样一步用正则表达式把地址匹配出来,还希望您能在下面留言,我想了几天也没弄出来。 您可以给我发邮件[email protected]
 
# 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()

你可能感兴趣的:(python,Google音乐,Google音乐下载)