爬取喜马拉雅音频,Python爬虫实战一之爬取QQ音乐

作者: 网络编程  发布:2019-12-18

风度翩翩、解析音频下载相关链接地址

一、前言


      这两日尝试爬取了博客园云音乐的歌曲,此次计划爬取QQ音乐的歌曲音信。博客园云音乐歌曲列表是通过iframe呈现的,可以信任Selenium获取到iframe的页面元素,

  而QQ音乐接受的是异步加载的主意,套路不相像,那是主流的页面加载形式,爬取有一点难度,但是也是对协调的三个挑衅。

 

1. 深入分析专辑音频列表页面

  在 PC端用 Chrome 浏览器中开采 喜马拉雅 网址,张开Chrome开辟者工具,随便张开三个节奏专辑页面,Chrome开拓者工具中回到如下图结果:

图片 1

  经过解析专辑音频列表地址为

  其中:

  • albumId 专辑ID
  • pageNum 页号

  再次回到的页面内容是 json 格式,比较于 html 源码,json 依然比较轻便管理的,下载音频只须要使用如下参数:

  • tracks 音频新闻列表
  • tracks -> title 音频标题
  • tracks -> trackId 音频ID

二、Python爬取QQ音乐单曲


事情未发生前看的慕课网的几个视频, 很好地执教了相同编写爬虫的步子,大家也按那一个来。

图片 2

          爬虫步骤

1.明确目的

率先大家要分明对象,此次爬取的是QQ音乐歌星刘德华先生的单曲。

(百度周全)->剖析指标(战略:url格式(范围)、数据格式、网页编码)->编写代码->执行爬虫

2.深入分析对象

 歌曲链接:

从侧面的截图可以见到单曲选取分页的秘技排列歌曲音信,每页展现30条,总共30页。点击页码大概最左边的">"会跳转到下风华正茂页,浏览器会向服务器发送ajax异步央浼,从链接能够见见begin和num参数,分别表示先河歌曲下标(截图是第2页,起头下标是30)和意气风发页重临30条,服务器响应再次来到json格式的歌曲音信(MusicJsonCallbacksinger_track({"code":0,"data":{"list":[{"Flisten_count1":......]}卡塔尔(英语:State of Qatar)),假若只是单身想拿到歌曲音讯,能够直接拼接链接伏乞和分析再次回到的json格式的多少。这里不选拔直接拆解深入分析数据格式的方式,笔者动用的是Python Selenium格局,每获得和深入分析完生龙活虎页的单曲新闻,点击 ">" 跳转到下风流倜傥页继续解析,直至解析并记录全数的单曲音信。最终号召每个单曲的链接,获取详细的单曲新闻。

图片 3

 

左侧的截图是网页的源码,全部歌曲信息都在类名叫mod_songlist的div浮层里面,类名称叫songlist_list的冬日列表ul下,每一种子成分li呈现二个单曲,类名称叫songlist__album下的a标签,满含单曲的链接,名称和时长等。

图片 4图片 5

 

3.编纂代码

1)下载网页内容,这里运用Python 的Urllib标准库,本人包装了二个download方法:

 1 def download(url, user_agent='wswp', num_retries=2):
 2     if url is None:
 3         return None
 4     print('Downloading:', url)
 5     headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
 6     request = urllib.request.Request(url, headers=headers)  # 设置用户代理wswp(Web Scraping with Python)
 7     try:
 8         html = urllib.request.urlopen(request).read().decode('utf-8')
 9     except urllib.error.URLError as e:
10         print('Downloading Error:', e.reason)
11         html = None
12         if num_retries > 0:
13             if hasattr(e, 'code') and 500 <= e.code < 600:
14                 # retry when return code is 5xx HTTP erros
15                 return download(url, num_retries-1)  # 请求失败,默认重试2次,
16     return html

 

2)解析网页内容,这里运用第三方插件BeautifulSoup,具体能够参见BeautifulSoup API 。

 1 def music_scrapter(html, page_num=0):
 2     try:
 3         soup = BeautifulSoup(html, 'html.parser')
 4         mod_songlist_div = soup.find_all('div', class_='mod_songlist')
 5         songlist_ul = mod_songlist_div[1].find('ul', class_='songlist__list')
 6         '''开始解析li歌曲信息'''
 7         lis = songlist_ul.find_all('li')
 8         for li in lis:
 9             a = li.find('div', class_='songlist__album').find('a')
10             music_url = a['href']  # 单曲链接
11             urls.add_new_url(music_url)  # 保存单曲链接
12             # print('music_url:{0} '.format(music_url))
13         print('total music link num:%s' % len(urls.new_urls))
14         next_page(page_num 1)
15     except TimeoutException as err:
16         print('解析网页出错:', err.args)
17         return next_page(page_num   1)
18     return None

 1 def get_music():
 2      try:
 3         while urls.has_new_url():
 4             # print('urls count:%s' % len(urls.new_urls))
 5             '''跳转到歌曲链接,获取歌曲详情'''
 6             new_music_url = urls.get_new_url()
 7             print('url leave count:%s' % str( len(urls.new_urls) - 1))
 8             html_data_info = download(new_music_url)
 9             # 下载网页失败,直接进入下一循环,避免程序中断
10             if html_data_info is None:
11                 continue
12             soup_data_info = BeautifulSoup(html_data_info, 'html.parser')
13             if soup_data_info.find('div', class_='none_txt') is not None:
14                 print(new_music_url, '   对不起,由于版权原因,暂无法查看该专辑!')
15                 continue
16             mod_songlist_div = soup_data_info.find('div', class_='mod_songlist')
17             songlist_ul = mod_songlist_div.find('ul', class_='songlist__list')
18             lis = songlist_ul.find_all('li')
19             del lis[0]  # 删除第一个li
20             # print('len(lis):$s' % len(lis))
21             for li in lis:
22                 a_songname_txt = li.find('div', class_='songlist__songname').find('span', class_='songlist__songname_txt').find('a')
23                 if 'https' not in a_songname_txt['href']:  #如果单曲链接不包含协议头,加上
24                     song_url = 'https:'   a_songname_txt['href']
25                 song_name = a_songname_txt['title']
26                 singer_name = li.find('div', class_='songlist__artist').find('a').get_text()
27                 song_time =li.find('div', class_='songlist__time').get_text()
28                 music_info = {}
29                 music_info['song_name'] = song_name
30                 music_info['song_url'] = song_url
31                 music_info['singer_name'] = singer_name
32                 music_info['song_time'] = song_time
33                 collect_data(music_info)
34      except Exception as err:  # 如果解析异常,跳过
35          print('Downloading or parse music information error continue:', err.args)

4.实施爬虫

爬虫跑起来了,一页一页地去爬取专辑的链接,并保存到集合中,最后通过get_music()方法获取单曲的名称,链接,歌手名称和时长并保存到Excel文件中。

2. 剖判音频下载链接地址

  随便播放二个节奏,在Chrome开拓者工具中回到如下图结果:

图片 6

  经过剖判专辑音频下载链接为

  其中

  • trackIds 音频ID

  再次回到的页面内容也是 JSON 格式,此中 tracksFor奥迪oPlay 字段富含了节奏的有关音信,其 src 便是音频下载地址。

  • src 音频下载链接
  • trackName 音频名称
  • trackId 音频ID

三、Python爬取QQ音乐单曲总计


1.单曲接纳的是分页方式,切换下大器晚成页是通过异步ajax央浼从服务器获取json格式的数量并渲染到页面,浏览器地址栏链接是不改变的,无法透过拼接链接来央浼。风华正茂开始想过都因此Python Urllib库来模拟ajax央求,后来考虑照旧用Selenium。Selenium能够很好地模拟浏览器真实的操作,页面成分定位也很便利,模拟单击下一页,不断地切换单曲分页,再经过BeautifulSoup深入解析网页源码,获取单曲音信。

 

2.url链接管理器,选择聚合数据构造来保存单曲链接,为何要动用集结?因为多个单曲只怕出自同生龙活虎专辑(专辑网站同样),那样能够减削须求次数。

 1 class UrlManager(object):
 2     def __init__(self):
 3         self.new_urls = set()  # 使用集合数据结构,过滤重复元素
 4         self.old_urls = set()  # 使用集合数据结构,过滤重复元素
 5     def add_new_url(self, url):
 6         if url is None:
 7             return
 8         if url not in self.new_urls and url not in self.old_urls:
 9             self.new_urls.add(url)
10 
11     def add_new_urls(self, urls):
12         if urls is None or len(urls) == 0:
13             return
14         for url in urls:
15             self.add_new_url(url)
16 
17     def has_new_url(self):
18         return len(self.new_urls) != 0
19 
20     def get_new_url(self):
21         new_url = self.new_urls.pop()
22         self.old_urls.add(new_url)
23         return new_url

 

3.由此Python第三方插件openpyxl读写Excel拾壹分方便,把单曲新闻通过Excel文件能够很好地保存起来。

1 def write_to_excel(self, content):
2     try:
3         for row in content:
4             self.workSheet.append([row['song_name'], row['song_url'], row['singer_name'], row['song_time']])
5         self.workBook.save(self.excelName)  # 保存单曲信息到Excel文件
6     except Exception as arr:
7         print('write to excel error', arr.args)

本文由金沙澳门官网发布于网络编程,转载请注明出处:爬取喜马拉雅音频,Python爬虫实战一之爬取QQ音乐

关键词: 金沙澳门官网

上一篇:Python之路,Day1 - Python基础1
下一篇:没有了