适合练手的Python小项目源码:爬虫、游戏与自动化工具
掌握Python基础语法之后,最有效的进阶方式是动手编写能够独立运行的小项目。本文挑选了爬虫、游戏与自动化工具三个方向中最具代表性且门槛适中的练手项目,提供完整可运行的源码,逐层拆解实现逻辑、环境依赖与关键排错点,帮助你在本地环境完成部署与调试。
一、三个练手方向的核心价值与选型定位
在开始写代码前,明确三个方向所锻炼的编程能力边界,有助于你根据自身学习目标合理分配精力。爬虫侧重于网络协议与数据解析,游戏侧重于状态流转与交互事件响应,而自动化工具侧重于底层文件系统调度与效率提升。
二、项目一(爬虫):图书数据采集与CSV导出
本项目抓取标准练习站点 quotes.toscrape.com 或同类型测试网站名言与作者信息,并将数据持久化为本地CSV文件。该站点专供爬虫学习使用,没有复杂的反爬机制,非常适合理解页面请求与标签提取流程。
1. 爬虫执行流程与实现步骤
一个标准的爬虫由初始化请求头、发送网络请求、解析DOM节点、组装结构化数据、持久化文件五个节点串联而成。流程图如下:
2. 环境准备与完整源码
在终端中安装项目所需的第三方库:
pip install requests beautifulsoup4
新建文件 quote_scraper.py,输入以下代码:
import csv
import sys
import requests
from bs4 import BeautifulSoup
def fetch_quotes():
target_url = "https://quotes.toscrape.com/"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
try:
response = requests.get(target_url, headers=headers, timeout=10)
response.raise_for_status()
except requests.RequestException as err:
print(f"网络请求失败: {err}")
sys.exit(1)
soup = BeautifulSoup(response.text, "html.parser")
quote_elements = soup.find_all("div", class_="quote")
scraped_data = []
for item in quote_elements:
text = item.find("span", class_="text").get_text(strip=True)
author = item.find("small", class_="author").get_text(strip=True)
tags = [tag.get_text(strip=True) for tag in item.find_all("a", class_="tag")]
scraped_data.append({
"quote": text,
"author": author,
"tags": ";".join(tags)
})
return scraped_data
def save_to_csv(data_list, filename="quotes.csv"):
if not data_list:
print("未提取到任何数据,跳过文件保存。")
return
fieldnames = ["quote", "author", "tags"]
with open(filename, mode="w", encoding="utf-8-sig", newline="") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data_list)
print(f"数据抓取成功,已写入文件: {filename},共计 {len(data_list)} 条记录。")
if __name__ == "__main__":
data = fetch_quotes()
save_to_csv(data)
encoding="utf-8-sig" 写入,可确保 Excel 自动识别为 UTF-8 编码。
三、项目二(游戏):经典贪吃蛇(Snake)
游戏开发是理解面向对象设计、循环调度以及二维离散坐标系的最佳实践。本项目使用轻量且成熟的 pygame 库,完整实现贪吃蛇的移动、键盘换向、吃食物长身体以及撞墙/撞自身判定。
1. 游戏主循环体系与状态更新
游戏运行时以固定频率(例如 10 FPS)反复执行三项任务:收集玩家操作、更新蛇身与食物坐标、重绘画面。架构关系如下:
2. 环境准备与完整源码
在终端中安装 Pygame 运行库:
pip install pygame
新建 snake_game.py,输入以下代码:
import sys
import random
import pygame
# 基础参数配置
WINDOW_WIDTH = 600
WINDOW_HEIGHT = 400
CELL_SIZE = 20
# 校验单元格与窗口对齐
assert WINDOW_WIDTH % CELL_SIZE == 0
assert WINDOW_HEIGHT % CELL_SIZE == 0
# 调色板
COLOR_BG = (242, 246, 250)
COLOR_SNAKE = (52, 94, 130)
COLOR_FOOD = (173, 128, 96)
COLOR_TEXT = (30, 41, 59)
def get_random_food(snake_body):
while True:
x = random.randint(0, (WINDOW_WIDTH // CELL_SIZE) - 1) * CELL_SIZE
y = random.randint(0, (WINDOW_HEIGHT // CELL_SIZE) - 1) * CELL_SIZE
if (x, y) not in snake_body:
return (x, y)
def run_game():
pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("贪吃蛇练手项目")
clock = pygame.time.Clock()
# 初始蛇身: 包含3个方块,初始向右移动
snake = [(100, 100), (80, 100), (60, 100)]
direction = (CELL_SIZE, 0)
food = get_random_food(snake)
score = 0
while True:
# 1. 监听事件与换向(防止直接掉头)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit(0)
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP and direction != (0, CELL_SIZE):
direction = (0, -CELL_SIZE)
elif event.key == pygame.K_DOWN and direction != (0, -CELL_SIZE):
direction = (0, CELL_SIZE)
elif event.key == pygame.K_LEFT and direction != (CELL_SIZE, 0):
direction = (-CELL_SIZE, 0)
elif event.key == pygame.K_RIGHT and direction != (-CELL_SIZE, 0):
direction = (CELL_SIZE, 0)
# 2. 状态更新:计算新蛇头
new_head = (snake[0][0] + direction[0], snake[0][1] + direction[1])
# 碰撞检测:撞墙或咬到自身
if (new_head[0] < 0 or new_head[0] >= WINDOW_WIDTH or
new_head[1] < 0 or new_head[1] >= WINDOW_HEIGHT or
new_head in snake):
print(f"游戏结束!最终得分: {score}")
pygame.quit()
return
snake.insert(0, new_head)
# 检查是否吃到食物
if new_head == food:
score += 1
food = get_random_food(snake)
else:
snake.pop()
# 3. 画面渲染
screen.fill(COLOR_BG)
# 绘制食物
food_rect = pygame.Rect(food[0], food[1], CELL_SIZE, CELL_SIZE)
pygame.draw.rect(screen, COLOR_FOOD, food_rect, border_radius=3)
# 绘制蛇身
for segment in snake:
seg_rect = pygame.Rect(segment[0], segment[1], CELL_SIZE, CELL_SIZE)
pygame.draw.rect(screen, COLOR_SNAKE, seg_rect, border_radius=2)
pygame.display.flip()
clock.tick(10) # 控制帧率,决定移动速度
if __name__ == "__main__":
run_game()
direction != (-CELL_SIZE, 0) 就是用于拦截这种反向操作。
四、项目三(自动化):下载目录文件分类归档工具
日常使用电脑时,默认的“下载”(Downloads)文件夹很容易积压大量不同扩展名的安装包、表格、压缩包和图片。编写一个自动化脚本,按照后缀名将文件自动投递到对应的子目录,是练习 Python 内置标准库 pathlib 与 shutil 的绝佳场景。
1. 规则匹配与归档逻辑
工具直接使用 Python 原生模块,无需安装外部第三方库。其核心工作流是遍历目录文件、比对扩展名字典、目标目录创建、安全移动。
import os
import shutil
from pathlib import Path
# 定义归档映射规则 (类别 -> 扩展名集合)
FILE_CATEGORIES = {
"文档": {".pdf", ".docx", ".doc", ".txt", ".xlsx", ".pptx", ".csv"},
"图片": {".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"},
"安装包": {".exe", ".msi", ".dmg", ".pkg", ".deb"},
"压缩文件": {".zip", ".rar", ".7z", ".tar", ".gz"},
"代码与脚本": {".py", ".html", ".css", ".js", ".json", ".sql"}
}
def organize_folder(target_folder_path):
folder = Path(target_folder_path)
if not folder.exists() or not folder.is_dir():
print(f"错误: 目标路径不存在或不是一个目录 -> {target_folder_path}")
return
moved_count = 0
for item in folder.iterdir():
# 忽略子文件夹与隐藏文件
if item.is_dir() or item.name.startswith("."):
continue
ext = item.suffix.lower()
matched_category = "其他杂项"
for category, extensions in FILE_CATEGORIES.items():
if ext in extensions:
matched_category = category
break
# 构建目标分类目录
target_dir = folder / matched_category
target_dir.mkdir(exist_ok=True)
target_file_path = target_dir / item.name
# 解决目标文件同名冲突:自动追加序号
counter = 1
stem = item.stem
while target_file_path.exists():
target_file_path = target_dir / f"{stem}_{counter}{ext}"
counter += 1
try:
shutil.move(str(item), str(target_file_path))
print(f"[已整理] {item.name} -> {matched_category}/")
moved_count += 1
except Exception as err:
print(f"[移动失败] {item.name}: {err}")
print(f"\n整理任务完毕,共迁移 {moved_count} 个文件。")
if __name__ == "__main__":
# 使用时替换为你的实际待整理文件夹路径
# 例如 Windows: r"C:\Users\YourUsername\Downloads"
# 例如 macOS/Linux: "/Users/YourUsername/Downloads"
test_path = "./test_downloads"
# 模拟创建测试目录与文件,便于直接运行验证
p = Path(test_path)
p.mkdir(exist_ok=True)
(p / "annual_report.xlsx").touch()
(p / "setup_installer.exe").touch()
(p / "profile_photo.png").touch()
(p / "notes.txt").touch()
print(f"正在对测试目录进行自动分类: {test_path}")
organize_folder(test_path)
while target_file_path.exists() 循环检查,并在存在重名文件时通过自增序列号重命名,确保原文件内容绝对不被意外擦除。
五、各项目技术架构与练习维度总结
三个练手项目覆盖了不同的技术栈与应用场景。为了在练习后能够融会贯通,我们将三者的核心特征、关键代码模块与扩展方向整理如下:
六、本地运行与排错指引
- Python环境版本: 上述三段源码均在 Python 3.8 及以上版本(包括 Python 3.10、3.11、3.12)测试通过。请尽量避免使用已停止维护的 Python 2.x。
-
依赖安装位置检查:
如果执行
python snake_game.py时出现ModuleNotFoundError: No module named 'pygame',说明安装 Pygame 的 pip 解释器与当前运行脚本的 Python 解释器不一致。可以使用python -m pip install pygame确保依赖安装到当前调用的 Python 环境中。 -
逐步调试验证:
建议不要一次性照搬所有代码。可以在本地新建单独的
.py脚本,先运行打印语句确认网络连通、窗口弹出或文件生成,再逐步追加判断逻辑与循环体系。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













