zoukankan      html  css  js  c++  java
  • 20201324 2020-2021-2 《Python程序设计》实验四报告

    20201324 2020-2021-2 《Python程序设计》实验四报告

    课程:《Python程序设计》
    班级: 2013
    姓名: 徐源
    学号:20201324
    实验教师:王志强
    实验日期:2021年6月23日
    必修/选修: 公选课

    (一)实验内容

    • 涉及知识:利用Python进行爬虫和数据处理
    • 具体操作:从QQ音乐爬取周杰伦的热门歌单,并用python一键为爬取到的每一首歌曲生成海报
    • 实验要求
      • (1)程序能运行,功能丰富。(需求提交源代码,并建议录制程序运行的视频)10分
      • (2)综合实践报告,要体现实验分析、设计、实现过程、结果等信息,格式规范,逻辑清晰,结构合理。10分。
      • (3)在实践报告中,需要对全课进行总结,并写课程感想体会、意见和建议等。5分

    下图为我用自己的程序生成的歌曲海报之一

    (二)实验过程及结果

    功能的实现分两步走,先爬虫得到歌单和歌曲信息,再利用这些信息生成海报

    1.爬取歌单

    打开页面->F12->Network->XHR

    找到client_search,点开,依次点击data->song->list->0,找到歌单上第一首歌的name:七里香

    说明这一部分有我们想要的数据,Headers->Request URL,编写代码

    代码如下

    import requests
    res_music = requests.get('https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&searchid=60997426243444153&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=20&w=%E5%91%A8%E6%9D%B0%E4%BC%A6&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0')
    json_music = res_music.json()
    

    2.挑拣所需数据

    分析知data是XHR的一个键,其对应的值也是一个字典;song是该字典的一个键,键song对应的值又是一个字典;list又是这个字典的一个值,其对应的值是一个列表,列表中的每一个元素都是一个字典,在每个字典里,键name的值即歌曲名,所以通过嵌套来获取歌曲名

    代码如下

    list_music = json_music['data']['song']['list']
    # list_music是一个列表,又嵌套了字典
    for music in list_music:
        # 以name为键,查找歌曲名
        print(music['name'])
        # 查找专辑名
        print('所属专辑:'+music['album']['name'])
        # 查找播放时长
        print('播放时长:'+str(music['interval'])+'秒')
        # 查找播放链接
        print('播放链接:https://y.qq.com/n/yqq/song/'+music['mid']+'.html')
        # 查找发布时间
        print('发布时间:'+str(music['time_public']))
        print('
    
    ')
    

    运行结果

    3.生成海报

    OpenCV不能显示中文字符,且难以控制文字位置。因此我对比性能后在OpenCV和PIL中选择了后者。

    安装库:pip install Pillow

    调用库函数:from PIL import Image, ImageDraw, ImageFont

    (1)准备海报底板

    对照QQ音乐页面显示的歌名,手动搜索图片作为海报底板,记得要将图片命名为歌曲名,并保存为png格式。这样程序运行时就知道"歌曲名.png"就是我们为《歌曲名》准备的底板,从而实现一键批量处理

    如何将jpg格式的图片转换成png格式

    img = title+".png" # 图片底板
    new_img = "final_"+title+".png" # 生成的海报
    

    为方便演示,我将代码修改为for music in list_music[0:3]:,仅为爬取到的前三首歌制作海报

    (2)调节字体格式、大小、颜色

    setFont = ImageFont.truetype('C:/Windows/Fonts/STXINWEI.TTF', 20)两个参数分别为字体在电脑中的路径和字体大小;

    颜色用CSS颜色或直接color = "black"均可

    (3)写入内容

    我使用了两种方式写入:

    单独写入一行字符

    draw.text(x,y), information, font=setFont, fill="#000000", direction=None)
    

    在底板上坐标(x,y)处开始写

    information是要写入的内容,必须是字符型

    将列表中的元素一行一行地打印出来

    summary_y = 0
    summary_line = 50
    summary = ['所属专辑:'+'《' + music['album']['name'] + '》', '歌曲时长:'+str(music['interval'])+'秒','歌手:周杰伦','发布时间:'+str(music['time_public'])]
    for num, one in enumerate(summary):
        y = summary_start_y - num * summary_line
        summary_num = num + 1
        draw.text((summary_x, height - y), u'%s. %s' % (summary_num, one), color, font)
    

    这样可以自动换行和标号,行距一致,方便快捷,强烈推荐!

    (4)生成海报

    image.save(new_img, 'png')

    做完一定要save一下,否则你会发现程序不报错,debug也没有问题,但就是没有你想要的海报(不要问我是怎么知道的/(ㄒoㄒ)/~~)

    代码如下(关键代码的功能已注释)

    # 图片名称
    img = title+".png" # 图片模板
    new_img = "final_"+title+".png" # 生成的图片
    
    # 设置字体样式
    font_type = "C:/Windows/Fonts/STXINWEI.TTF"
    font_medium_type = "C:/Windows/Fonts/STKAITI.TTF"
    header_font = ImageFont.truetype(font_type, 55)
    title_font = ImageFont.truetype(font_type, 45)
    font = ImageFont.truetype(font_medium_type, 20)
    # ImageFont.truetype第一个参数为字体,第二个为字体大小
    color = "#000000"
    
    
    # 打开图片
    image = Image.open(img)
    draw = ImageDraw.Draw(image)
    width, height = image.size
    # 获取原图像的宽和高,并保持最终海报的大小与之一致
    
    
    # 写入header
    header_x = 40
    header_y = 650
    # 数字越小,字在图片上的位置越偏下
    draw.text((header_x, height - header_y), u'%s' % header, color, header_font)
    
    
    # 写入标题
    title_x = header_x
    title_y = header_y - 80
    draw.text((title_x, height - title_y), u'%s' % title, color, title_font)
    
    
    # 写入歌曲信息
    summary_x = title_x
    summary_start_y = title_y - 150
    # title后面减的越多,字越偏下
    summary_y = 0
    summary_line = 50
    information = '歌曲信息'
    setFont = ImageFont.truetype('C:/windows/fonts/STXINGKA.TTF', 25)
    draw.text((summary_x, height - summary_start_y-40), information, font=setFont, fill="#000000", direction=None)
    for num, one in enumerate(summary):
        y = summary_start_y - num * summary_line
        summary_num = num + 1
        draw.text((summary_x, height - y), u'%s. %s' % (summary_num, one), color, font)
    
    
    # 写入链接
    write_x = summary_x
    write_y = title_y - 400
    write_line = 40
    information = '播放链接:'
    setFont = ImageFont.truetype('C:/windows/fonts/STXINGKA.TTF', 25)
    draw.text((write_x, height - write_y), information, font=setFont, fill="#000000", direction=None)
    draw.text((write_x, height - write_y + write_line), writes, font=font, fill="#0000ff", direction=None)
    
    # 生成图片
    image.save(new_img, 'png')
    

    运行结果

    (三)实验过程中遇到的问题和解决过程

    • 问题1:设置字体时报错OSError: cannot open resource
    • 问题1解决方案:百度,发现之前写的路径不完整,必须写成"C:/Windows/Fonts/xxx.TTF"的形式

    • 问题2:在往底板写入文字时,部分字段的长度会超出图片大小,导致无返显示在底板上

    image

    • 问题2解决方案:
      • 在挑选大小合适的图片作为底板
      • 调整写入字符的坐标。网上的资料有限,我直接人工排查。逐个修改程序中的坐标值,运行程序,记录字段的坐标,找出规律。最终将字符坐标修改为合适的值

    (四)参考资料

    Python在图片中添加文字的两种方法

    python PIL图像处理-图片上添加文字

    Windows字体文件存放位置

    如何将jpg格式的图片转换成png格式

    (五)佐证材料

    码云链接:https://gitee.com/xu-yuan-20201324/python_use/blob/main/Socket_test/crawler_homework.py

    操作视频已录制并发送至指定邮箱

    (六) 其他(课程总结、感想、建议)

    我之所以报名python程序设计课是因为优秀学长学姐的强烈推荐。大一菜狗,网上选课时紧张到手一直在抖,系统一开放,我第一时间狂点python,抢到的那一刻当场开心到不能自已。

    这门课带给了我什么?——它真的让我吃了很多苦,这学期我一直严格按照王老师“今日事,今日毕”的理念要求自己,作业一定要当天晚上就做,做不完就熬夜继续做。我的天赋和基础委实都很一般,以至于这学期90%以上的作业都是半夜提交的。做实验三时,因为第一次接触密码方面的知识,操作不规范,外加以前的种种问题相继暴露,我的电脑不幸经历了一波猛烈的故障o(TヘTo),导致这学期所有的python文件、之前做过的作业和实验报告、精心整理的课堂笔记,统统从本地清零了,码云仓库也被清空了。真的算得上是我遇到的最大的打击,那天我对自己说:“想哭就哭吧”,但发了很久的呆,最后还是程序从头重编,实验报告从零重写,然后,就这么过去了。

    如果能重新做一次选择,我想,我还是会义无反顾。python程序设计课不仅提高了我的编程能力,加深了我对c语言等专业课内容的认识,也给了我一个机会,让我在探索新世界的过程中不断磨砺与成长。遇到问题时,学会问百度,学会总结经验,这是一种能力。如今的我,可以冷静地拆解问题、建立思路、动手实现,能静得下心来分析以前看一眼就觉得头大的网络开源代码,能在碰壁时心态平和地从新来过,这些能力放在任何领域都是宝贵的财富。

    如果说有什么小建议的话,希望老师把函数、文件处理、爬虫等部分,结合具体例子,讲得再详细些吧。感觉前面简单的知识讲得很细,到了后面较难的部分反而不如前面细致了,也可能是我的理解能力跟不上了,嘿嘿嘿。这些部分的资源也请老师提前放到云班课上吧,课程刚开始时时间比较充足,后面可能没时间看了,不想浪费好资源。

    最后,真诚感谢王老师一学期的精心指导,真的收获满满!

  • 相关阅读:
    P5737 【深基7.例3】闰年展示
    P1200 [USACO1.1]你的飞碟在这儿Your Ride Is Here
    P1597 语句解析
    P5735 【深基7.例1】距离函数
    P1553 数字反转(升级版)
    P1598 垂直柱状图
    P1603 斯诺登的密码
    P5738 【深基7.例4】歌唱比赛
    Ext.GridPanel 用法总结(一)—— Grid基本用法
    使用CodeSmith快速规范开发.Net软件
  • 原文地址:https://www.cnblogs.com/cqszxy2020/p/14934826.html
Copyright © 2011-2022 走看看