欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-26 22:30:21
...
Google音乐做的不错,不过可能由于家里网络的的原因,经常听着听着就不动了,就想着下到本地听,不知道他怎么做的,在Internet临时文件夹里看不到音乐的临时文件,从网上只找到一个下载的工具是用PYTHON做的,不过不合我的要求,于是决定自己写一个。
python 分析Google音乐下载地址(一)
标题
 我比较喜欢听Google整理的专辑,所以就从这里开始了,比如这个页面(http://www.google.cn/music/topiclistingq=top100_north_south_line&cat=song)查看他的源码,发现音乐下载页面的地址是下面红字的部分(<a href="javascript:void(0)" title="下载" οncοntextmenu="return false;"οnclick="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好像不支持向前预匹配,这个表达式不能用,从网上找了好长时间也没有找到解决的办法,只能用比较的笨的办法了。
  我的思路是这样的,先把‘下载" οncοntextmenu="return false;" οnclick="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我也不会,也是现学现用),最后匹配出来的是“下载" οncοntextmenu="return false;" οnclick="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()就行了,最后得出来的地址是
当然这个地址不是音乐的下载地址,只是下载页面的地址,还得分析那个页面才能得到真正的下载的地址,当我用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开发工程师,这里有我自己整理了一套最新的python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。想要这些资料的可以关注小编,也可以加入学习交流群1097572481
 
相关标签: python 编程语言