循环语法之编程模拟音乐播放器

发布时间 2023-10-17 21:43:08作者: hsy2093

以音乐播放器软件的界面作为导入


提问学生:如果需要自己生成一个歌单,在歌单中有哪些较为重要的组成部分?
提取关键元素:歌曲名;歌手;歌曲顺序

编程实现一:利用顺序结构实现一个简单的歌单

回顾字符串类型与print()函数,实现下列代码

songname1 = "画"
songname2 = "借我"
songname3 = "秋酿"
print(songname1)
print(songname2)
print(songname3)

提问学生:如果这个歌单中有一百首歌曲,那么这样写法的代码存在什么问题?
答:代码行数过多,重复性过高

编程实现二:利用列表与循环结构实现歌单

回顾列表类型的使用,新学for循环结构语法,实现下列代码

songname = ["画", "借我", "秋酿"]
for i in songname:
    print(i)

编程实现三:补充其余歌单元素

提问学生:一个歌单中如果只有歌曲名字是否完整?
回答:不完整,还需要序号和歌手名
如何补充其余元素?

实现方法1: 写多个循环输出

#输出序号
index = ["1", "2", "3"]
for i in index:
    print(i)
#输出歌曲名
songname = ["画", "借我", "秋酿"]
for i in songname:
    print(i)
#输出歌手名
singer = ["赵雷", "谢春花", "房东的猫"]
for i in singer:
    print(i)

输出结果

1
2
3
画
借我
秋酿
赵雷
谢春花
房东的猫

提问学生:这样的写法好吗?
回答:不够直观,序号与歌曲名字、歌手名对应不上
提问学生:一个合格的歌单中是怎么呈现这三种元素的?
回答:在同一行中呈现一首歌曲的所有信息
总结:因此希望在一个for循环中,就能将歌曲所有的信息输出

实现方法2: 通过下标来索引列表元素(range函数实现)

思考同一首歌曲的信息在元素中的存在位置?
列表的索引下标相同
因此可以通过只循环下标参数,一次获取到每一首歌曲的所有信息
且对应的下标应该是:0, 1, 2
介绍新函数,range()函数的使用方法

for i in range(3):
    print(i)

现在下标的表示方法已知,可以通过一个循环打印完整的歌单

index = ["1", "2", "3"]
songname = ["画", "借我", "秋酿"]
singer = ["赵雷", "谢春花", "房东的猫"]
for i in range(3):
    print(index[i] + " " +  songname[i] + " " + singer[i])

实现方法三(不用range函数实现)

引导学生思考,除了用range函数来索引下标,我们定义的哪个元素与下标形式很像?
是否可以通过index作为下标?

index = ["1", "2", "3"]
songname = ["画", "借我", "秋酿"]
singer = ["赵雷", "谢春花", "房东的猫"]
for i in index:
    print(index[i-1] + " " +  songname[i-1] + " " + singer[i-1])

编程实现四:实现列表循环播放歌单

提问学生:普通的音乐播放软件中除了顺序播放,还有哪些播放选项?
学生回答:列表循环、随机循环、单曲循环
提问:现在时间长度为30,歌单中只有三首歌,如何体现该情景下的列表循环?
引导学生归纳思考不同时间段对应的歌曲下标,从而得出通过取余操作实现列表循环

songname = ["画", "借我", "秋酿"]
singer = ["赵雷", "谢春花", "房东的猫"]
for i in range(30):
    print(str(i+1) + " " +  songname[i%3] + " " + singer[i%3])

编程实现五:实现在歌单中存储五十首歌的信息

提问学生:之前学习的批量获取信息的方法还有印象吗?
回答:python爬虫
介绍python爬虫相关库以及xlrt库,实现用爬虫获取五十首歌曲并且打印输出
爬虫代码:

import xlwt
import requests
from bs4 import BeautifulSoup
import re


def get_url(url):
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        print('wrong!!!!!!!!!!!!!')


def singer_url(url):
    # 只抓取前10位的歌手
    html = get_url(url)
    soup = BeautifulSoup(html, 'html.parser')
    top_10 = soup.find_all('div', attrs={'class': 'u-cover u-cover-5'})
    singers = []
    for i in top_10:
        singers.append(
            re.findall(r'.*?<a class="msk" href="(/artist\?id=\d+)" title="(.*?)的音乐"></a>.*?', str(i))[0])  # 问号有问题
        # 解析的代码和源代码的顺序不同,在用正则表达式的时候要注意
    song_info(singers)


def song_info(singers):
    url = 'http://music.163.com'

    for singer in singers:
        try:
            new_url = url + str(singer[0])
            songs = get_url(new_url)
            soup = BeautifulSoup(songs, 'html.parser')

            Info = soup.find_all('textarea', attrs={'style': 'display:none;'})[0]
            songs_url_and_name = soup.find_all('ul', attrs={'class': 'f-hide'})[0]
            # print(songs_url_and_name)

            datas = []
            data1 = re.findall(r'"album".*?"name":"(.*?)".*?', str(Info.text))
            data2 = re.findall(r'.*?<li><a href="(/song\?id=\d+)">(.*?)</a></li>.*?', str(songs_url_and_name))

            for i in range(len(data2)):
                datas.append([data2[i][1], data1[i], 'http://music.163.com/#' + str(data2[i][0])])
            # print(datas)
            save_excel(singer, datas)
        except:
            continue


def save_excel(singer, datas):
    fpath = '/Users/hsy/Desktop'
    book = xlwt.Workbook()
    sheet1 = book.add_sheet('sheet1', cell_overwrite_ok=True)
    sheet1.col(0).width = (25 * 256)
    sheet1.col(1).width = (30 * 256)
    sheet1.col(2).width = (40 * 256)
    # xlwt中列宽的值表示方法:默认字体0的1/256为衡量单位。
    # xlwt创建时使用的默认宽度为2960,既11个字符0的宽度
    # 所以我们在设置列宽时可以用如下方法:
    # width = 256 * 20    256为衡量单位,20表示20个字符宽度

    heads = ['歌曲名称', '专辑', '歌曲链接']
    count = 0

    print('正在存入文件......')
    for head in heads:
        sheet1.write(0, count, head)
        count += 1

    i = 1
    for data in datas:
        j = 0
        for k in data:
            sheet1.write(i, j, k)
            j += 1
        i += 1

    book.save(fpath + str(singer[1]) + '.xls')  # 括号里写存入的地址
    print('OK!')


def main():
    url = 'http://music.163.com/discover/artist/cat?id=1001'  # 华语男歌手页面
    singer_url(url)


main()

运行效果部分截图

歌曲信息输出代码:

import xlrd #读取excel的库

resArray=[] #先声明一个空list
data = xlrd.open_workbook("/Users/hsy/Desktop/chou.xls") #读取文件
table = data.sheet_by_index(0) #按索引获取工作表,0就是工作表1
songname = table.col_values(0) #读取每行数据,保存在line里面,line是list
album = table.col_values(1)
for i in range(50):
    print("time", i+1)
    print(songname[i], "--", album[i])