平时喜欢用百度音乐随便找个歌单听听歌,一来搜索打开方便,二来歌曲曲目也全。今天在找歌单的时候,突然想看看热门歌单里都有哪里歌曲,于是便有了这个小程序。
首先,需要获取各个歌单的地址,我们从百度音乐的歌单首页入手:
图中红框的为歌单的当前的数目,页面每一页有20个歌单,也就是有20个URL,我们把它提取出来:
# 获取歌单 def get_song_list(page): songListUrl = 'http://music.baidu.com/songlist/tag/%E5%85%A8%E9%83%A8?orderType=1&offset={0}'.format(page) print(songListUrl) wbdata = requests.get(songListUrl).content soup = BeautifulSoup(wbdata,'lxml') songListLink = soup.select("p.text-title > a ") for s in songListLink: title = s.get('title') link = s.get('href') data = { "title":title, "link":link } song_list.insert_one(data) print("数据写入成功")
存入数据库之后,就有了下面的结果:
有了歌单的URL地址,我们访问看看:
一个歌单的内页就像这样,在这里,我们只提取出红框中的信息,就是歌单的名称、歌单的创建者、歌单的标签、歌单的播放次数、歌单歌曲的曲名、演唱者和专辑。
在网页上按F12打开调试工具,找到上述信息对应的位置,进行匹配。
# 获取歌单详细信息 def get_songlist_info(songlisturl): proxies = { "http": "http://{0}".format(random.choice(prolist)), } try: url = "http://music.baidu.com"+songlisturl print(url) wbdata = requests.get(url).content soup = BeautifulSoup(wbdata,'lxml') # 歌单名字 list_name = soup.h1.get_text() # 创建者 list_user = soup.find(name="a",class_="songlist-info-username").get_text() # 歌单标签 list_tags = soup.select("div.songlist-info-tag > a")[0].get_text() # 播放次数 list_count = soup.find(name="span",class_="songlist-listen").get_text() # 收藏次数 list_collect = soup.find(name="em",class_="collectNum").get_text() # 歌单歌曲 list_music = soup.select("div.normal-song-list.song-list.song-list-hook.clear.song-list-btnBoth.song-list-btnTop.song-list-btnBottom > ul > li") for m in list_music: sdata = json.loads(m['data-songitem']) sname = sdata['songItem']['sname'] sauthor = sdata['songItem']['author'] data = { "list_name":list_name, "list_user":list_user, "list_count":list_count, "list_collect":list_collect, "list_tage":list_tags, "sname":sname, "sauthor":sauthor, } songlist_info.insert_one(data) print(data) except BaseException as e: # error_link.insert_one(songlisturl) print("程序运行出错:%s" % e) # error_link.insert_one(songlisturl)
最后,使用多线程或者多进程对函数进行调用。
一共爬取了5000余歌单总计10万的歌曲信息,部分截图如下:
完整爬虫代码的下载链接,关注微信公众号:州的先生,回复关键字:百度歌单爬虫
文章版权所有:州的先生博客,转载必须保留出处及原文链接