Skip to content

Instantly share code, notes, and snippets.

@Wizmann
Last active December 16, 2015 18:21
Show Gist options
  • Save Wizmann/5477394 to your computer and use it in GitHub Desktop.
Save Wizmann/5477394 to your computer and use it in GitHub Desktop.
下载虾米音乐
# coding=utf-8
import gevent
import gevent.monkey
gevent.monkey.patch_all()
import gevent.queue
import requests
import sys
import re
import os
import urllib
import urllib2
import xml.etree.cElementTree as ET
'''
TODO:
整个专辑打包下载,所以引用了gevent模块,多协程下载
Thanks to:http://jixun.org/1748-xiami-dl-link-parse/
'''
def dLoc(sLocation):
num = int(sLocation[0])
inp = sLocation[1:]
iLe = len(inp) % num
ret = ''
arr = []
for i in xrange(num):
arr.append((1 if iLe > i else 0) + (len(inp) - iLe) / num)
for i in xrange(max(arr)):
a = 0
for j in xrange(num):
if a + i >= len(inp):
continue
ret += inp[a + i]
a += arr[j]
ret = urllib.unquote(ret[0: len(inp)])
ret = re.sub('\^', '0', ret)
ret = re.sub('\+', ' ', ret)
return ret
def from_id_to_url(idx):
ua = {'User-Agent':
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31'}
xml = requests.get(
"http://www.xiami.com/song/playlist/id/" + idx, headers=ua).text.encode('utf-8')
tree = ET.fromstring(xml)
curl = ''
title = ''
for elem in tree.iter():
if 'location' in elem.tag:
curl = elem.text
if 'title' in elem.tag:
title = elem.text
if not curl or not title:
return ('', '')
else:
return (title, dLoc(curl))
def download(title, url):
r = urllib2.Request(url)
r.add_header('User-Agent',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31')
u = urllib2.urlopen(r)
meta = u.info()
file_size = int(meta.getheaders("Content-Length")[0])
file_size_dl = 0
block_sz = 8192
with open(title + '.mp3', 'wb') as f:
while True:
buffer = u.read(block_sz)
if not buffer:
break
file_size_dl += len(buffer)
f.write(buffer)
status = r"%10d [%3.2f%%]" % (
file_size_dl, file_size_dl * 100. / file_size)
status = status + chr(8) * (len(status) + 1)
print status,
if __name__ == '__main__':
if len(sys.argv) != 2:
print "参数错误"
else:
title, url = from_id_to_url(sys.argv[1])
print title, url
if title and url:
download(title, url)
else:
print "音乐信息错误"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment