python爬虫实践之爬取千千音乐

目录

概述

准备

所需模块

涉及知识点

运行效果

完成爬虫

1. 分析网页

2. 爬虫代码


概述

爬取千千音乐的音乐资源,下载音频文件。

准备

所需模块

  • re
  • urllib.request
  • requests
  • lxml

涉及知识点

  • python基础
  • requests模块基础
  • re模块基础
  • xpath表达式基础

运行效果

控制台打印:

电脑本地文件:

完成爬虫

1. 分析网页

打开千千音乐网,按F12分析网页

在这里可以使用xpath表达式获取每一个a标签的文本值。

选择一个电视剧,作为测试用:http://music.taihe.com/tag/%E7%94%B5%E8%A7%86%E5%89%A7

其中进入分类页面的URL拼接是:

"http://music.taihe.com/tag"+分类类型

当然要在这里对中文进行处理。

由于该分类下有很多歌曲,并有分页,因此点浏览到页面最下方翻到第2页:

第2页的URL是:http://music.taihe.com/tag/%E7%94%B5%E8%A7%86%E5%89%A7?start=20&size=20&third_type=0

那么第3页的URL是:http://music.taihe.com/tag/%E7%94%B5%E8%A7%86%E5%89%A7?start=40&size=20&third_type=0

再回到第1页,其URL是:http://music.taihe.com/tag/%E7%94%B5%E8%A7%86%E5%89%A7?start=0&size=20&third_type=0

因此可以得出每一页的URL:

# 第1页的URL: http://music.taihe.com/tag/%E7%94%B5%E8%A7%86%E5%89%A7?start=0&size=20&third_type=0
# 第2页的URL: http://music.taihe.com/tag/%E7%94%B5%E8%A7%86%E5%89%A7?start=20&size=20&third_type=0
# 第3页的URL: http://music.taihe.com/tag/%E7%94%B5%E8%A7%86%E5%89%A7?start=40&size=20&third_type=0
# 因此可以得出URL的公式: url="http://music.taihe.com/tag/"+song_type+"?start="+(page_index-1) * 20+"&size=20&third_type=0"
# 其中song_type是歌曲分类的类型,page_index指的是页码

然后分析某一页中各首歌曲的信息,发现:

即可通过这个ID进行拼接前往歌曲具体页面的URL。

接着是爬取每一首音乐的信息

选择一首音乐进行分析:

这些信息可以拼接URL直接进行请求获取。

请求的URL是这样的:

song_info_url = "http://musicapi.taihe.com/v1/restserver/ting?method=baidu.ting.song.playAAC&format=jsonp&songid=" + song_id
# song_id指的是歌曲的ID

在浏览器打开mp3的歌曲链接,即是我们需要的

2. 爬虫代码

import re
import urllib.request

import requests
from lxml import etree

# python实战: 下载千千音乐的音乐资源
# 千千音乐: http://music.taihe.com/tag

# 第1页的URL: http://music.taihe.com/tag/%E7%94%B5%E8%A7%86%E5%89%A7?start=0&size=20&third_type=0
# 第2页的URL: http://music.taihe.com/tag/%E7%94%B5%E8%A7%86%E5%89%A7?start=20&size=20&third_type=0
# 第3页的URL: http://music.taihe.com/tag/%E7%94%B5%E8%A7%86%E5%89%A7?start=40&size=20&third_type=0
# 因此可以得出URL的公式: url="http://music.taihe.com/tag/"+song_type+"?start="+(page_index-1) * 20+"&size=20&third_type=0"
# 其中song_type是歌曲分类的类型,page_index指的是页码

# 请求头
header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36"
}
# 歌曲分类标签的URL
tag_url = "http://music.taihe.com/tag"
# 获取请求页面的源码
tag_data = requests.get(tag_url, headers=header).content
# 将HTML源码字符串转换成HTML对象
tag_html = etree.HTML(tag_data)
# 通过xpath表达式获取热门分类名称
tag_name_list = tag_html.xpath("//div[@class='mod-tag clearfix']//dl[@monkey='tzz']//a")
# 用来保存分类文本名称
tag_name_text_list = []
# 循环遍历分类名称
for i in range(0, len(tag_name_list)):
    tag_name_text_list.append(tag_name_list[i].text)
    print(str(tag_name_list[i].text) + "\t\t\t", end="")  # end=""是为了消除print()函数的自动换行
    if i != 0 and i % 6 == 0:
        print("\n")
print("\n")  # 换行
# 要下载的歌曲类型
song_type = input("请选择要下载的歌曲类型: ")
if song_type not in tag_name_text_list:
    print("该类别不在可选择分类中,请重新选择!")
else:
    # 获取下载页数
    page_num = int(input("请输入您要下载的页数: "))
    for page_index in range(0, page_num):
        # 拼接URL
        song_url = "http://music.taihe.com/tag/" + urllib.request.quote(song_type) + "?start=" + str(
            page_index * 20) + "&size=20&third_type=0"  # urllib.request.quote()解决处理中文在URL中的问题
        # 发送请求,获取响应
        response = requests.get(song_url, headers=header).content.decode()
        # 根据正则表达式匹配每首歌曲的ID
        song_ids = re.findall("/song/(\d*)", response)
        # 取消ID中的重复项
        song_id_list = set(song_ids)
        # 循环遍历歌曲ID
        for song_id in song_id_list:
            # 根据歌曲的ID组装URL
            song_info_url = "http://musicapi.taihe.com/v1/restserver/ting?method=baidu.ting.song.playAAC&format=jsonp&songid=" + song_id
            # 发送请求获取歌曲的详细信息,返回的是JSON格式数据
            song_info_data = requests.get(song_info_url).content.decode()
            # 处理反斜杠的问题
            song_info_format_data = re.sub(r"\\", "", song_info_data)
            # 获取歌曲名字的正则表达式
            pat_song_name = re.compile(r'"title":"(.*?)",')
            # 获取歌曲名字
            song_name_list = pat_song_name.findall(song_info_format_data)
            # 获取歌曲音频文件的正则表达式
            pat_song_media_file = re.compile(r'"show_link":"(.*?)",')
            # 获取歌曲音频文件的链接
            song_media_file_list = pat_song_media_file.findall(song_info_format_data)
            # 获取歌曲的歌词文件的正则表达式
            pat_song_lrc_file = re.compile(r'"lrclink":"(.*?)",')
            # 获取歌曲的歌词文件的链接
            song_lrc_file_list = pat_song_lrc_file.findall(song_info_format_data)
            # 判断条件
            if len(song_name_list) == len(song_media_file_list) == len(song_lrc_file_list):
                # 循环遍历
                for i in range(0, len(song_name_list)):
                    # 下载提示
                    print("正在下载: " + song_name_list[i] + "......")
                    # 下载音乐音频到本地
                    with open(r"C:/Users/Administrator/Music/qianqian/" + song_name_list[i] + ".mp3",
                              "wb") as media_file_object:
                        # 获取音乐音频文件的数据
                        song_media_data = requests.get(song_media_file_list[i]).content
                        # 下载到本地
                        media_file_object.write(song_media_data)
                    # 下载音乐歌词到本地
                    with open(r"C:\\Users\\Administrator\\Music\\qianqian\\" + song_name_list[i] + ".lrc",
                              "wb") as lrc_file_object:
                        # 获取音乐歌词文件的数据
                        song_lrc_data = requests.get(song_lrc_file_list[i]).content
                        # 下载到本地
                        lrc_file_object.write(song_lrc_data)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值