Python多线程爬取QQ音乐的专辑信息
来源:互联网 发布:梦幻古龙服务端源码 编辑:程序博客网 时间:2024/06/10 11:50
1 需求:
获取专辑信息:
专辑名字,歌手,流派,语种,发行时间,发行公司,类型,介绍
以及专辑中的歌曲,歌手和时长
全部保存为json格式
2 分析页面
专辑链接所在的url为上图右方的链接:去掉多余参数则如下图所示:
page从0开始。
观察专辑的链接,
红框中的内容恰好是一图中的album_mid所对应的值。
打开专辑链接,要获取的内容如下:
通过多次试着爬取,发现专辑中的信息并不统一,大概分为5类:
第一类:就是上图完整的类型
第二类:即完整类型中缺少了一个,要么是类型,要么是发行公司。需要进行判断。
第三类:
如图:没有歌手名字,并且是四个小字段。需要写判断。
第四类:
和上图是同种类型,但是是3个小字段。依旧需要写判断。
第五类:
这两种情况属于请求失败,当请求失败时,会直接返回null。此时创建空字典,让所有键对应的值为空。
下面是代码,写的不好,请多指教。
1 qq_music.py
# -*- coding: utf-8 -*-"""获取专辑信息专辑名字,歌手,流派,语种,发行时间,发行公司,类型,简介专辑中的歌曲,歌手和时长数据全部存储为json格式(qqMusic0.json)"""import requestsimport jsonfrom bs4 import BeautifulSoupimport headers_fileimport loggingimport timeimport sysreload(sys)sys.setdefaultencoding('utf-8')logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='qqM.log', filemode='w')class QQMusic: def __init__(self): pass # 获取所有专辑的链接 def getAlbumLinks(self): album_links = [] for page_num in range(1000): # page从0开始 base_url = 'https://c.y.qq.com/v8/fcg-bin/album_library?cmd=get_album_info&page='+str(page_num)+'&pagesize=20&sort=1' logging.info(base_url) time.sleep(10) page = requests.get(base_url, headers=headers_file.request_headers()) html = page.content # 替换掉开头结尾,用于json和字典的转换 html2 = html.replace('MusicJsonCallback(', '') html3 = html2.replace('})', '}') html_dict = json.loads(html3) album_list = html_dict['data']['albumlist'] # 获取关键字album_mid的内容,拼接成专辑的链接 for album in album_list: link_id = album['album_mid'] # print link_id album_link = 'https://y.qq.com/n/yqq/album/'+str(link_id)+'.html' album_links.append(album_link) return album_links # 获取专辑的详细信息 def getAlbumInfo(self, url): logging.info(url) album_dict = {} # 创建字典储存所有信息 try: time.sleep(20) info_page = requests.get(url, headers=headers_file.request_headers()) info_html = info_page.text # print info_html soup = BeautifulSoup(info_html, 'html.parser') album_name = soup.find_all('h1', class_='data__name_txt')[0].get_text(strip=True) # 专辑名称 album_dict['album_name'] = album_name # 有的也没有歌手,没有歌手信息的,以下5个小信息对应的key不同。 # 多出来的演奏,译名舍掉,key值存为空 singer = soup.find_all('a', class_='js_singer data__singer_txt') # 歌手 if len(singer) == 0: info_all = soup.find_all('li', class_='data_info__item') # 演奏,发行时间,发行公司,译名,类型。 album_dict['singer'] = "null" album_dict['music_genre'] = "null" album_dict['language'] = "null" # 有的也没有类型 if len(info_all) == 4: pub_time = info_all[1].get_text(strip=True) # 发行时间 pub_company = info_all[2].get_text(strip=True) # 发行公司 album_dict['pub_time'] = pub_time album_dict['pub_company'] = pub_company # album_type = info_all[3].get_text(strip=True) # 类型 album_dict['album_type'] = 'null' # 这个条件下有的info_all长度只有3, 只有发行公司、发行时间、类型 elif len(info_all) == 3: pub_time = info_all[0].get_text(strip=True) # 发行时间 pub_company = info_all[1].get_text(strip=True) # 发行公司 album_dict['pub_time'] = pub_time album_dict['pub_company'] = pub_company album_type = info_all[2].get_text(strip=True) # 类型 album_dict['album_type'] = album_type else: pub_time = info_all[1].get_text(strip=True) # 发行时间 pub_company = info_all[2].get_text(strip=True) # 发行公司 album_dict['pub_time'] = pub_time album_dict['pub_company'] = pub_company album_type = info_all[4].get_text(strip=True) # 类型 album_dict['album_type'] = album_type else: singer2 = singer[0].get_text(strip=True) album_dict['singer'] = singer2 info_all = soup.find_all('li', class_='data_info__item') # 流派,语种,发行时间,发行公司,类型等信息在一起 # 有的没有发行公司,长度为4,完整的5个都有,长度为5 # 突然发现,有的也没有类型。。。。 if len(info_all) == 4: music_genre = info_all[0].get_text(strip=True) # 流派 language = info_all[1].get_text(strip=True) # 语种 pub_time = info_all[2].get_text(strip=True) # 发行时间 unknown = info_all[3].get_text(strip=True) if '发行公司' in unknown: pub_company = unknown album_dict['pub_company'] = pub_company # 发行公司 album_dict['album_type'] = "无" if '类型' in unknown: album_type = unknown album_dict['album_type'] = album_type # 专辑类型 album_dict['pub_company'] = "无" album_dict['music_genre'] = music_genre album_dict['language'] = language album_dict['pub_time'] = pub_time else: music_genre = info_all[0].get_text(strip=True) # 流派 language = info_all[1].get_text(strip=True) # 语种 pub_time = info_all[2].get_text(strip=True) # 发行时间 pub_company = info_all[3].get_text(strip=True) # 发行公司 album_type = info_all[4].get_text(strip=True) # 专辑类型 album_dict['music_genre'] = music_genre album_dict['language'] = language album_dict['pub_time'] = pub_time album_dict['pub_company'] = pub_company album_dict['album_type'] = album_type album_intro = soup.find_all('div', class_='about__cont')[0].get_text(strip=True) # 专辑简介 album_dict['album_intro'] = album_intro # 有的专辑简介为空 if len(album_intro) == 0: album_intro = "null" album_dict['album_intro'] = album_intro # 专辑内的所有歌曲信息 song_list = [] songs = soup.find_all('span', class_='songlist__songname_txt') # 歌名 for i in songs: song = i.get_text(strip=True) song_list.append(song) artist_list = [] artists = soup.find_all('div', class_='songlist__artist') # 演唱者 for i in artists: artist = i.get_text(strip=True) artist_list.append(artist) time_list = [] song_time = soup.find_all('div', class_='songlist__time') # 时长 for i in song_time: time_minute = i.get_text(strip=True) time_list.append(time_minute) album_info = zip(song_list, artist_list, time_list) album_info2 = [] for item in album_info: songs_list = dict() songs_list['song'] = item[0] songs_list['who_sing'] = item[1] songs_list['time'] = item[2] album_info2.append(songs_list) album_dict['album_info2'] = album_info2 # print album_dict, url return album_dict except Exception as e: logging.info(e) # 有的页面会请求失败,一个是版权无法查看,一个是找不到该页面,此时返回空字典,value全部为null album_dict['album_name'] = "null" album_dict['singer'] = "null" album_dict['music_genre'] = "null" album_dict['language'] = "null" album_dict['pub_time'] = "null" album_dict['pub_company'] = "null" album_dict['album_type'] = "null" album_dict['album_intro'] = "null" album_dict['album_info2'] = "null" return album_dict
2 music_thread.py
# -*- coding: utf-8 -*-import threadingimport Queuefrom qq_music import *q = Queue.Queue()lock = threading.Lock()qm = QQMusic()class MusicThread(threading.Thread): def __init__(self, queue): threading.Thread.__init__(self) self.queue = queue def run(self): while True: if self.queue.qsize() > 0: url = self.queue.get() f = open('qqMusic0.json', 'a+') try: content = qm.getAlbumInfo(url) lock.acquire() f.write(json.dumps(content)+'\n') lock.release() f.close() except Exception as e: logging.error(e) continue else: logging.warn('none') breakdef main(): for url in qm.getAlbumLinks(): # print url q.put(url) ts = [] for i in range(20): t = MusicThread(q) t.setDaemon(True) t.start() ts.append(t) for t in ts: t.join()if __name__ == '__main__': main()
3 headers_file.py
用来轮换user_agent
昂,有一个错误:
这是在服务器上跑数据,日志中写入的错误。应该是请求过快了,设置睡眠也无济于事,只好在本机上自己跑数据了。
有没有知道这该怎么处理的小伙伴呐,多谢指教。啦啦啦啦~~~
0 0
- Python多线程爬取QQ音乐的专辑信息
- Python爬虫入门(六)爬取披头士乐队历年专辑封面-网易云音乐
- python使用scrapy爬取qq音乐(一)
- python使用scrapy爬取qq音乐(二)
- qq音乐专辑封面 api
- 获取本地音乐文件的专辑,图片,音乐信息
- 仿QQ音乐播放器播放音乐时专辑图片的圆形和旋转
- 仿QQ音乐专辑图标旋转
- python爬取落网音乐
- Python-爬取百度音乐
- Python 爬取百度音乐
- QQ音乐信息架构
- 高仿QQ音乐之旋转专辑图片的实现—仿留声机效果
- Python 爬取喜马拉雅FM中‘冬吴同学会’专辑
- 用Python爬取用户虾米音乐的歌单
- 【python】 网易云音乐 专辑图片+歌词
- Python爬取信息的方法
- IOS的后台模式播放音乐,显示专辑和图片信息
- Spring的职能----IOC
- Student类,包括学生姓名、性别、年龄、Java成绩。要求创建五个该类对象,输出每个学生信息,计算并输出这五个学生Java成绩的平均值, 以及计算并输出他们Ja
- zero-copy零拷贝
- 数组中有一个数字出现一次,其余数字均出现两次,求出出现一次的那个数字。
- CF贪心刷题记录
- Python多线程爬取QQ音乐的专辑信息
- 相关性计算
- Android中 intent 显式启动与隐式启动
- HTML5新增表单元素
- LeetCode064 Minimum Path Sum
- 多线程系列提高(4)--同步容器类
- 1006. 换个格式输出整数 (15)
- 线程同步工具之CountDownLatch
- 登山