Python教程

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

本文主要是介绍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('\n\n')

运行结果

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语言等专业课内容的认识,也给了我一个机会,让我在探索新世界的过程中不断磨砺与成长。遇到问题时,学会问百度,学会总结经验,这是一种能力。如今的我,可以冷静地拆解问题、建立思路、动手实现,能静得下心来分析以前看一眼就觉得头大的网络开源代码,能在碰壁时心态平和地从新来过,这些能力放在任何领域都是宝贵的财富。

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

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

这篇关于20201324 2020-2021-2 《Python程序设计》实验四报告的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!