110
社区成员




课程:《Python程序设计》
班级: 2323
姓名: 李劲源
学号:20232312
实验教师:王志强
实验日期:2024年5月16日
必修/选修: 公选课
1)实验要求
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
课代表和各小组负责人收集作业(源代码、视频、综合实践报告)
编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。
利用公开数据集,开展图像分类、恶意软件检测等
利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。
爬取天气数据,实现自动化微信提醒
利用爬虫,实现自动化下载网站视频、文件等。
编写小游戏:坦克大战、贪吃蛇、扫雷等等
注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。
(2)本实验聚焦内容
运用python库和python代码,编写一个桌面助手程序,集成:日历与备忘录 、 天气查询 、 快速搜索 、 任务清单、视频下载等功能
为了帮助用户在一个平台上快速方便地获取和管理信息,本实验旨在开发一个桌面助手应用程序,提供多种日常使用的功能,包括天气查询、快捷查询、待办事项管理、日历和提醒,以及视频下载功能。受《鲁滨逊漂流记》中那个主人公鲁滨逊的原始人助手兼伙伴星期五的启发,我将本程序命名为**F.R.I.D.A.Y.**,希望它能成为你的计算机小助手~
应用涵盖了以下五个主要功能模块:
1. **日历和提醒**:让用户添加和查看日程事件和提醒。
2. **天气预报**:通过 OpenWeatherMap API 获取并显示指定城市的详细天气信息。
3. **快捷查询**:快速在搜索引擎中查询输入的内容,链接浏览器并搜索。
4. **待办事项**:管理日常待办事项,轻松标记已完成任务。
5. **视频下载**:通过 yt-dlp 下载指定 URL 的视频。
我们使用 tkinter
图形用户界面库来开发桌面助手应用。应用主界面使用 ttk.Notebook
控件创建选项卡,每个选项卡对应一个功能模块。主类 DesktopAssistant
负责初始化和管理各功能模块。
import tkinter as tk # 导入tkinter库并重命名为tk
from tkinter import ttk, messagebox # 从tkinter库中导入ttk模块和messagebox模块
from tkcalendar import Calendar, DateEntry # 从tkcalendar库中导入Calendar和DateEntry小部件
import requests # 导入requests库,用于发送HTTP请求和处理响应
import webbrowser # 导入webbrowser库,用于在默认的Web浏览器中打开指定的URL
import yt_dlp # 导入yt_dlp库,用于下载符合协议的视频(查过官网有好多好多,基本上国内外主流视频网站都能下载)
日历和提醒:
tkcalendar
库提供日历显示功能。天气预报:
快捷查询:
待办事项:
视频下载:
我们首先创建主界面,使用 ttk.Notebook
创建各个功能模块的选项卡,并实例化每个功能类。
class DesktopAssistant:
def __init__(self, root):
self.root = root
self.root.title("桌面助手")
self.tab_control = ttk.Notebook(root)
self.tab1 = ttk.Frame(self.tab_control)
self.tab2 = ttk.Frame(self.tab_control)
self.tab3 = ttk.Frame(self.tab_control)
self.tab4 = ttk.Frame(self.tab_control)
self.tab5 = ttk.Frame(self.tab_control)
self.tab_control.add(self.tab1, text='日历和提醒')
self.tab_control.add(self.tab2, text='天气预报')
self.tab_control.add(self.tab3, text='快捷查询')
self.tab_control.add(self.tab4, text='待办事项')
self.tab_control.add(self.tab5, text='视频下载')
self.tab_control.pack(expand=1, fill="both")
self.calendar_app = CalendarApp(self.tab1)
self.weather_app = WeatherApp(self.tab2)
self.query_app = QueryApp(self.tab3)
self.todo_app = TodoApp(self.tab4)
self.video_downloader_app = VideoDownloaderApp(self.tab5)
class CalendarApp:
def __init__(self, parent):
self.parent = parent
self.calendar = Calendar(parent)
self.calendar.pack(pady=10)
self.event_label = tk.Label(parent, text="添加事项")
self.event_label.pack(pady=5)
self.event_entry = tk.Entry(parent)
self.event_entry.pack(pady=5)
self.reminder_label = tk.Label(parent, text="提醒时间 (时间格式为HH:MM):")
self.reminder_label.pack(pady=5)
self.reminder_entry = tk.Entry(parent)
self.reminder_entry.pack(pady=5)
self.add_event_button = tk.Button(parent, text="Add Event", command=self.add_event)
self.add_event_button.pack(pady=10)
self.events = {}
def add_event(self):
date = self.calendar.get_date()
event = self.event_entry.get()
reminder = self.reminder_entry.get()
if not event or not reminder:
messagebox.showwarning("Missing Information", "Please enter both event and reminder time")
return
if date not in self.events:
self.events[date] = []
self.events[date].append((event, reminder))
messagebox.showinfo("Event Added", f"Event '{event}' added on {date} with reminder at {reminder}")
class WeatherApp:
def __init__(self, parent):
self.parent = parent
self.city_label = tk.Label(parent, text="输入城市:")
self.city_label.pack(pady=5)
self.city_entry = tk.Entry(parent)
self.city_entry.pack(pady=5)
self.get_weather_button = tk.Button(parent, text="查询天气", command=self.get_weather)
self.get_weather_button.pack(pady=10)
self.weather_result = tk.Label(parent, text="", justify=tk.LEFT)
self.weather_result.pack(pady=10)
def get_weather(self):
city = self.city_entry.get()
api_key = 'Your_API_Key' # 替换为API,这里不把我的放出来了
url = f'https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric'
response = requests.get(url)
if response.status_code == 200:
weather_data = response.json()
temp = weather_data['main']['temp']
feels_like = weather_data['main']['feels_like']
humidity = weather_data['main']['humidity']
wind_speed = weather_data['wind']['speed']
weather_desc = weather_data['weather'][0]['description']
weather_main = weather_data['weather'][0]['main']
self.weather_result.config(
text=f"当前气温(摄氏度): {temp}°C\n"
f"体感温度(摄氏度): {feels_like}°C\n"
f"湿度: {humidity}%\n"
f"风速: {wind_speed} m/s\n"
f"天气: {weather_main} - {weather_desc}\n"
)
else:
self.weather_result.config(text="Could not retrieve weather information.")
class QueryApp:
def __init__(self, parent):
self.parent = parent
self.query_label = tk.Label(parent, text="输入你想搜索的内容:")
self.query_label.pack(pady=5)
self.query_entry = tk.Entry(parent)
self.query_entry.pack(pady=5)
self.search_button = tk.Button(parent, text="搜索", command=self.search)
self.search_button.pack(pady=10)
def search(self):
query = self.query_entry.get()
if not query:
messagebox.showwarning("Missing Query", "Please enter a query")
return
url = f'https://www.baidu.com/s?wd={query}'
webbrowser.open(url)
class TodoApp:
def __init__(self, parent):
self.parent = parent
self.todo_label = tk.Label(parent, text="输入待办事项:")
self.todo_label.pack(pady=5)
self.todo_entry = tk.Entry(parent)
self.todo_entry.pack(pady=5)
self.add_todo_button = tk.Button(parent, text="添加", command=self.add_todo)
self.add_todo_button.pack(pady=10)
self.todo_listbox = tk.Listbox(parent)
self.todo_listbox.pack(pady=10)
self.delete_todo_button = tk.Button(parent, text="已完成", command=self.delete_todo)
self.delete_todo_button.pack(pady=10)
self.todos = []
def add_todo(self):
todo = self.todo_entry.get()
if todo:
self.todos.append(todo)
self.todo_listbox.insert(tk.END, todo)
self.todo_entry.delete(0, tk.END)
else:
messagebox.showwarning("Missing Todo", "Please enter a todo item")
def delete_todo(self):
try:
selected_idx = self.todo_listbox.curselection()[0]
self.todo_listbox.delete(selected_idx)
del self.todos[selected_idx]
except IndexError:
messagebox.showwarning("No Selection", "Please select a todo item to delete")
class VideoDownloaderApp:
def __init__(self, parent):
self.parent = parent
self.url_label = tk.Label(parent, text="输入视频网址:")
self.url_label.pack(pady=5)
self.url_entry = tk.Entry(parent)
self.url_entry.pack(pady=5)
self.download_button = tk.Button(parent, text="下载视频", command=self.download_video)
self.download_button.pack(pady=10)
self.status_label = tk.Label(parent, text="", justify=tk.LEFT)
self.status_label.pack(pady=10)
def download_video(self):
url = self.url_entry.get()
if not url:
messagebox.showwarning("Missing URL", "Please enter a video URL")
return
ydl_opts = {
'outtmpl': '%(title)s.%(ext)s', # 视频文件输出路径和文件名
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
self.status_label.config(text="下载完成、已保存在同一文件夹下")
except Exception as e:
self.status_label.config(text=f"下载失败: {str(e)}")
class VideoDownloaderApp:
def __init__(self, parent):
self.parent = parent
self.url_label = tk.Label(parent, text="输入视频网址:")
self.url_label.pack(pady=5)
self.url_entry = tk.Entry(parent)
self.url_entry.pack(pady=5)
self.download_button = tk.Button(parent, text="下载视频", command=self.download_video)
self.download_button.pack(pady=10)
self.status_label = tk.Label(parent, text="", justify=tk.LEFT)
self.status_label.pack(pady=10)
def download_video(self):
url = self.url_entry.get()
if not url:
messagebox.showwarning("Missing URL", "Please enter a video URL")
return
ydl_opts = {
'outtmpl': '%(title)s.%(ext)s', # 视频文件输出路径和文件名
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
self.status_label.config(text="下载完成、已保存在同一文件夹下")
except Exception as e:
self.status_label.config(text=f"下载失败: {str(e)}")
问题1:在完成下载视频的功能时出现提示
ERROR: You have requested merging of multiple formats but ffmpeg is not instaled. Aborting due to --abort-on-error
问题1解决方案:通过询问ChatGPT,我得知这个错误提示表明 yt-dlp 在尝试将多个不同格式的音视频流合并为单个文件时,发现系统缺少 ffmpeg 这个工具,因此无法进行合并操作。于是我用管理员权限下载了Chocolatey并在powershell中输入
choco install ffmpeg
添加到计算机的path中(还得用管理员权限)
安装了ffmpeg、视频得以顺利下载
问题2:在 JSON 数据解析过程中,天气 API 返回的数据格式与预期不符,导致程序无法正确解析数据并更新界面显示。
问题2解决方案:通过登录访问的API官网(OpenWeather)查询有关说明,获取格式内容即可。相比前一个问题较为容易解决。
在完成了一学期的Python程序设计的课程学习后,回首,的确学到了不少东西,亦产生了些许感悟,故于此稍作记录,在偌大的互联网中留点痕迹。
回想起来这也不是我第一次接触Python了。之前在高中时曾在学校的信息技术课上接触过Python语言,这应该算是我接触的第一门高级计算机语言,仍清楚记得用的是IDLE,现在回想起来还是漫游感触的。虽然当时的学习只是停留在一些input
,水仙花数、字典元组等较浅的层面,但这也成了我选修这门课程、遇见王老师的契机。
Python语言还是相当简洁干练且高效的。
先前曾听闻“人生苦短、我用Python”这一有意思的说法,而在我怀着一颗敬畏的心、深入学习Python的过程中,我逐渐理解了这一句话的含金量,或者说Python的含金量。王老师善用比喻,于是我想如果把C语言比作只热情但麻烦的二哈的话,Python更像一只机智优雅的边牧。简洁的语法、丰富的标准库、动态数据... 可以说无不扣动着无数码农的心弦。
这一学期的Python课程还是学到了相当多的东西的。
这里就不一一例举了。
其中印象最深刻的还是老师讲的“炒饭”和“盖浇饭”。于我而言敲代码其实是一个很极端的体验。虽然在调试bug的时候可谓是满怀悲痛,但当你看着你倾注心血的程序正常运行茁壮成长时,有种孩子终于长大了的喜悦。我其实课外自己完成了许多Python程序的编写。从“全自动骚扰信息发送器”的骚扰信息脚本到“爬死你不偿命”爬虫程序,其实还是很有成就感的。
王老师讲课相当生动有趣,故给人一种极佳的上课体验。所以关于讲课方面我其实没什么太大的建议,但其实老师可以尝试在平时去布置一些练习,给同学们上手操作的机会。如果可行的话,还可以衔接一些有关网络安全内容的东西(例如Python脚本),毕竟我们是干这个的对吧:)
不善言辞,但心存感激不知所言,故于此向王老师致以最诚挚的敬意。