#encoding:utf8
import requests
import re
from bs4 import BeautifulSoup
from lxml import etree
class xiaMi:
def __init__(self):
self.root_url = "http://www.xiami.com/search?key="
self.head = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.3831.602 Safari/537.36"}
def get_html(self,url):
if url == "":
return
html = requests.get(url,headers=self.head)
if html.status_code != 200:
return
else:
return html.text
def related_songs(self,response):
songs = []
for tr in BeautifulSoup(response,"lxml").find_all("tr"):
xpath = etree.HTML(str(tr))
try:
song_name = xpath.xpath('//*[@class="song_name"]/a/text()')[0]#歌曲名
song_artist = xpath.xpath('//*[@class="song_artist"]/a/text()')[0]#歌手
song_album = "".join(xpath.xpath('//*[@class="song_album"]/a/text() | //*[@class="song_album"]/a/b/text()'))#专辑
sid = re.match(r'\w+\(\'(\d+)\',\'\d+\'\)',xpath.xpath('//*[@class="song_act"]/div/a[@class="song_digg"]/@onclick')[0]).group(1)
songs.append({"song_name":song_name,"song_artist":song_artist.strip(),"song_album":song_album,"sid":sid})
except:
pass
if songs == []:
return False
return songs
def parse_url(self,song_id):
url = "http://www.xiami.com/widget/xml-single/uid/0/sid/"+song_id
sid = re.compile('CDATA\[(.*?)\]', re.S).findall(requests.get(url,headers=self.head).text)[4]
num_loc = sid.find('h')#获取当前h的下标 改下标为1
rows = int(sid[0:num_loc])#获取第一个数字
strlen = len(sid) - num_loc#用该字符串减去h出现的下标得到的长度
cols = int(strlen / rows)#用长度除以第一位数字得到的串数
right_rows = strlen % rows#用长度除以第一位数字得到的余数
new_s = sid[num_loc:]#获取h以后的所有元素
output = ''
for i in range(len(new_s)):
x = i % rows
y = int(i / rows)
p = 0
if x <= right_rows:
p = x * (cols + 1) + y
else:
p = right_rows * (cols + 1) + (x - right_rows) * cols + y
output += new_s[int(p)]
return requests.utils.unquote(output).replace('^', '0')
def get_download_link(self,name,url):
print("开始下载%s"%name)
musice = requests.get(url,headers=self.head).content
with open("music/%s.mp3"%name,"wb") as f:
f.write(musice)
print("%s下载完成"%name)
def dio(self):
while True:
select = input("搜索歌曲,退出q:")
if select.lower() == "q":
exit(0)
else:
html = self.get_html(self.root_url+select)
songs = self.related_songs(html)
if songs == False:
print("输入的歌名有误!")
continue
for i in range(len(songs)):
print("%d %s\t%s\t%s"%(i+1,songs[i]["song_name"],songs[i]["song_artist"],songs[i]["song_album"]))
sid = int(input("请选择:"))-1
print("您选择的是\t《%s》\t的\t《%s》"%(songs[sid]["song_artist"],songs[sid]["song_name"]))
download_url = self.parse_url(songs[sid]["sid"])
self.get_download_link(songs[sid]["song_name"],download_url)
if __name__ == '__main__':
wode = xiaMi()
wode.dio()