/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}
简介:面向Python初学者的源码实例合集,集中了100个可独立运行的python程序,覆盖文件处理、网络爬虫、数据分析、图形用户界面、小游戏开发等常见练习场景。每个实例都配有可供直接运行的python源码,部分实例额外附带txt说明文档、html结果展示页、js交互脚本、xml配置文件或css美化样式,便于对照学习代码结构、运行逻辑以及前后端联调的基本思路。整个资源包共2003个文件,其中1751个py文件为绝对主体,另有133个txt说明、37个html页面、30个js文件、21个xml及16个css等辅助材料,压缩包整体大小74.29MB,目录按实例序号组织,检索定位相当方便。已有2752人学习下载,适合正在刷题巩固语法、准备课程设计或希望借助经典案例提升编程能力的初学者,按实例逐个调试也能较快积累排错经验。
1. 项目定位与价值:从"拿来就跑"到"改造成自己的工具箱"
如果你手头有一套覆盖爬虫、GUI、数据处理、自动化办公、小游戏等场景的python100个源码实例,最直观的用法不是挨个看,而是把它当成一个"代码仓库":遇到需求时,翻到对应分类,复制、改参数、跑起来。这套资源里的每一个实例都是完整可独立运行的脚本,不是零碎的功能片段,有入口函数、有注释、有运行说明。刚学完语法的人可以照着代码逐行理解,赶工期的人可以直接提取中间件或爬虫逻辑改造成自己的服务。它适合所有想把Python落到实际任务的人,哪怕你只写过练习题,也能通过这份资源少走弯路。
2. 资源全貌与架构设计:100个实例如何组织、技术栈选型
2.1 目录结构与分类逻辑
拿到源码之后,先看目录。整套资源采用按功能分层的目录结构,每个实例独立放在一个文件夹里,内部至少包含一个 .py 文件和一个 README.md 说明文件。这样做的好处是:每个实例可以单独运行,不依赖其他文件夹;同时实例之间没有共享全局变量,避免相互污染。
目录大致如下:
python100/
├── 01_basic_syntax/ # 基础语法实例
│ ├── 01_fibonacci/
│ │ ├── fibonacci.py
│ │ └── README.md
│ └── 02_list_comprehension/
├── 02_file_processing/ # 文件与目录处理
│ ├── 01_batch_rename/
│ ├── 02_log_parser/
│ └── 03_csv_splitter/
├── 03_network/ # 网络与爬虫
│ ├── 01_http_downloader/
│ ├── 02_news_crawler/
│ └── 03_proxy_checker/
├── 04_gui/ # 桌面GUI
│ ├── 01_calculator/
│ ├── 02_to_do_list/
│ └── 03_file_manager/
├── 05_data_processing/ # 数据处理与可视化
│ ├── 01_excel_cleaner/
│ ├── 02_time_series_plot/
│ └── 03_json_to_sqlite/
├── 06_automation/ # 自动化办公
│ ├── 01_word_report/
│ ├── 02_email_sender/
│ └── 03_pdf_merger/
├── 07_game/ # 小游戏
│ ├── 01_guess_number/
│ └── 02_tetris_basic/
├── 08_tools/ # 常用小工具
│ ├── 01_qrcode_generator/
│ └── 02_pdf_password_remover/
└── requirements.txt # 全局依赖清单
目录命名有规律:数字前缀表示难度或顺序,后面的英文词描述功能。我一般会先看 03_network 和 05_data_processing ,因为这两个分类里的实例最能直接转化为工作产出,比如爬虫保存 Excel、日志解析生成报表。
2.2 技术栈与依赖清单
requirements.txt 里列出的依赖并不多,核心是第三方库。整套资源基于 Python 3.8+ 开发,兼容 3.10、3.11。常用依赖如下:
| requests | HTTP 请求、爬虫 | 03_category 下大部分实例 |
| beautifulsoup4 | HTML 解析、数据抽取 | 新闻爬虫、商品列表 |
| pandas | 数据清洗、表格处理 | 05_data_processing 全部 |
| matplotlib | 图表绘制 | 时间序列、统计图 |
| openpyxl | 读写 Excel .xlsx | 自动化报表 |
| PyQt5 或 tkinter | GUI 界面 | 04_gui 分类 |
| reportlab | 生成 PDF | 02_file_processing |
选择这些库的理由很直白:它们是 Python 生态里最稳定、文档最全的,遇到报错时搜索一下就能找到解决方案。GUI 实例中 tkinter 是标准库,不额外安装,适合入门;少数实例用 PyQt5 做复杂布局,可以视作进阶参考。
除了第三方库,每个实例内部会尽量只用标准库完成基础功能,比如 json 、 csv 、 re 、 os 、 argparse 等。这样当你把某个实例单独拷走时,不需要安装一大堆依赖。
2.3 实例之间的设计约定
源码实例不是随手写的脚本,它们有一致的写法约定,目的是让你能快速理解并在多个实例之间互相复制代码。每条约定在 README.md 里都有一句话说明。
约定一:每个实例的入口函数叫 main() ,并且放在文件末尾调用。调用前会有一个 if __name__ == '__main__': 判断。这样既能单独运行,也能被其他脚本 import 后复用。
约定二:输入路径和输出路径都通过 argparse 从命令行传入,硬编码路径只出现在默认值里。比如爬虫实例默认输出到当前目录,但你可以用 –output 参数指定。
约定三:日志统一使用 logging 标准库,输出到控制台的同时,可选写入文件。这样你看到 INFO 日志时,知道这是正常流程, ERROR 是出错点。
约定四:所有对外提供的函数都有 docstring 描述输入输出。这不仅是文档习惯,更是为了让你在二次开发时能直接用 help() 查看参数含义。
比如 02_log_parser 实例中的部分代码:
import argparse
import logging
import re
from collections import Counter
logging.basicConfig(level=logging.INFO, format='%(asctime)s – %(levelname)s – %(message)s')
def parse_log(file_path, top_n=10):
"""从日志文件中提取IP并统计出现次数。
Args:
file_path (str): 日志文件路径。
top_n (int): 返回出现次数最多的前N个IP。
Returns:
list: 列表元素为 (IP地址, 出现次数) 元组。
"""
ip_pattern = r'\\b(?:[0-9]{1,3}\\.){3}[0-9]{1,3}\\b'
ip_counter = Counter()
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
ips = re.findall(ip_pattern, line)
ip_counter.update(ips)
return ip_counter.most_common(top_n)
def main():
parser = argparse.ArgumentParser(description='日志IP统计工具')
parser.add_argument('logfile', help='日志文件路径')
parser.add_argument('–top', type=int, default=10, help='统计数量前N')
args = parser.parse_args()
result = parse_log(args.logfile, args.top)
for ip, count in result:
print(f'{ip}\\t{count}')
if __name__ == '__main__':
main()
这段代码解析日志文件里的 IP 地址,统计出现次数。 argparse 让命令行用法变得清晰, re 的正则表达式匹配 IPv4, Counter 负责排序。如果你需要统计的不是 IP 而是别的字段,比如 URL、用户 ID,只改 ip_pattern 和对应的解析逻辑就行。
这样的设计约定让你在组装多个实例时非常顺手。比如把日志分析的输出接到后续的自动化报表实例,只需要在代码里调用 parse_log 函数,而不是通过文件中间结果传递。
3. 核心模块代码拆解:爬虫、GUI与数据处理实例的运行逻辑
3.1 网络爬虫实例:抓取公开数据并保存为CSV
03_network/02_news_crawler 是一个典型的爬虫实例,目标是从一个简单的新闻列表页抓取标题、发布时间和正文摘要,保存到 CSV。这里隐去了真实网站,用 example.com 代替。
import requests
from bs4 import BeautifulSoup
import csv
import time
import argparse
def fetch_page(url):
"""获取页面HTML,失败时重试两次。"""
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
for attempt in range(3):
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
return response.text
except requests.RequestException as e:
print(f'第{attempt + 1}次请求失败: {e}')
time.sleep(2)
return None
def parse_news(html):
"""解析新闻列表页,提取标题、链接、摘要。"""
soup = BeautifulSoup(html, 'html.parser')
news_items = []
# 假设页面结构:每个新闻条目是 <div class="news-item">
for item in soup.select('div.news-item'):
title_tag = item.select_one('h2 a')
summary_tag = item.select_one('p.summary')
if title_tag is None:
continue
title = title_tag.text.strip()
link = title_tag.get('href')
summary = summary_tag.text.strip() if summary_tag else ''
news_items.append({
'title': title,
'link': link,
'summary': summary,
})
return news_items
def save_to_csv(news_items, filename):
"""将新闻数据写入CSV文件。"""
with open(filename, 'w', newline='', encoding='utf-8-sig') as f:
fieldnames = ['title', 'link', 'summary']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(news_items)
def main():
parser = argparse.ArgumentParser(description='新闻列表爬虫')
parser.add_argument('url', help='目标URL')
parser.add_argument('–output', default='news.csv', help='输出CSV文件路径')
args = parser.parse_args()
html = fetch_page(args.url)
if html is None:
print('无法获取页面,退出')
return
items = parse_news(html)
save_to_csv(items, args.output)
print(f'成功保存 {len(items)} 条新闻到 {args.output}')
if __name__ == '__main__':
main()
这段代码有三个关键点。一是 fetch_page 里设置了重试机制,网络波动时不会立刻失败,而是休息 2 秒再试,三次失败才放弃,这比裸 requests.get 可靠得多。二是 parse_news 使用 select 方法,按 CSS 选择器定位目标元素,比嵌套 find 更清爽,以后网站结构变化时改选择器即可。三是 save_to_csv 指定了 UTF-8-SIG 编码,这样生成的 CSV 在 Windows 上用 Excel 打开不会中文乱码。
运行方式很简单: python news_crawler.py https://example.com/news –output today_news.csv 。如果要抓取多页,常见做法是循环调用 fetch_page 并拼接 URL 参数,然后在代码里加一个 for page in range(1, total_pages) 。需要注意请求频率,加 time.sleep(1) 避免被封。
3.2 GUI实例:用tkinter搭建一个简易计算器
04_gui/01_calculator 展示了用 tkinter 写一个带按钮的图形界面。它比命令行交互更直观,适合日常小工具快速实现。
import tkinter as tk
from tkinter import messagebox
def calculate():
try:
expression = display.get()
result = eval(expression)
display.delete(0, tk.END)
display.insert(0, str(result))
except (SyntaxError, ZeroDivisionError, NameError):
messagebox.showerror('错误', '表达式不合法')
def button_click(char):
display.insert(tk.END, char)
def clear():
display.delete(0, tk.END)
root = tk.Tk()
root.title('简易计算器')
root.geometry('300×400')
display = tk.Entry(root, font=('Arial', 20), justify='right')
display.pack(fill=tk.BOTH, padx=10, pady=10)
buttons = [
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'0', '.', 'C', '+',
]
row = 0
col = 0
for btn in buttons:
if btn == 'C':
cmd = clear
else:
cmd = lambda b=btn: button_click(b) # 注意用默认参数固化循环变量
button = tk.Button(root, text=btn, font=('Arial', 15), command=cmd)
button.grid(row=row, column=col, sticky='nsew', padx=2, pady=2)
col += 1
if col > 3:
col = 0
row += 1
equal_btn = tk.Button(root, text='=', font=('Arial', 20), command=calculate)
equal_btn.grid(row=row, column=0, columnspan=4, sticky='nsew', padx=2, pady=2)
root.mainloop()
这里最容易踩坑的是 lambda 表达式。如果写成 lambda: button_click(btn) ,Python 闭包会记住 btn 的循环引用,最终所有按钮都点击同一个值。所以代码里用了默认参数 lambda b=btn ,把当前值固化成参数。这个技巧在写 GUI 或批量绑定事件时非常常见。
eval 函数可以执行字符串里的表达式,但安全风险高。原作者给出的实例只用于本地桌面工具,没接触网络输入。如果你要改成网络服务,就需要换成 ast.literal_eval 或写一个简单解析器,否则等于把服务器大门打开。
3.3 数据处理实例:用pandas清洗并可视化Excel数据
05_data_processing/01_excel_cleaner 处理的场景是:拿到一份包含缺失值、重复行、格式混乱的 Excel,经过清洗后得到结构化数据,并输出一张汇总图。这是办公自动化里最高频的需求。
import pandas as pd
import matplotlib.pyplot as plt
import argparse
def clean_data(input_file):
"""读取Excel,清洗数据并返回DataFrame。"""
df = pd.read_excel(input_file, engine='openpyxl')
# 1. 删除完全重复的行
df = df.drop_duplicates()
# 2. 删除所有列都为空的无效行
df = df.dropna(how='all')
# 3. 填充重要字段的缺失值,比如销售金额填0
if 'amount' in df.columns:
df['amount'] = df['amount'].fillna(0)
# 4. 将日期列统一格式
if 'date' in df.columns:
df['date'] = pd.to_datetime(df['date'], errors='coerce')
df = df.dropna(subset=['date'])
# 5. 移除明显异常值,比如金额为负数(业务上不可能)
if 'amount' in df.columns:
df = df[df['amount'] >= 0]
return df
def visualize_by_category(df):
"""按分类字段统计金额并绘制柱状图。"""
if 'category' in df.columns and 'amount' in df.columns:
summary = df.groupby('category')['amount'].sum().sort_values(ascending=False)
summary.plot(kind='bar', figsize=(10, 6))
plt.title('Amount by Category')
plt.xlabel('Category')
plt.ylabel('Total Amount')
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('category_summary.png', dpi=100)
plt.close()
def main():
parser = argparse.ArgumentParser(description='Excel数据清洗工具')
parser.add_argument('input', help='输入Excel路径')
parser.add_argument('–output', default='cleaned.xlsx', help='清洗后输出路径')
args = parser.parse_args()
cleaned_df = clean_data(args.input)
cleaned_df.to_excel(args.output, index=False, engine='openpyxl')
visualize_by_category(cleaned_df)
print(f'清洗完成,数据量: {len(cleaned_df)} 行,图表已保存')
if __name__ == '__main__':
main()
清洗逻辑每一步都有序:先去除完全重复行,再删掉空白行,然后针对业务字段做缺失值和异常值处理。 pd.to_datetime 遇到无法解析的日期会变成 NaT ,再用 dropna 剔除,这样就不会让脏数据混进结果。
数据量大的时候, to_excel 比 to_csv 慢,但胜在保留多工作表。如果你需要在同一份输出里放多个结果表,可以额外加一个 ExcelWriter 对象。这个实例本身不追求性能,侧重点是把业务规则变成可复现的数据管道。
4. 运行环境与避坑实战:让100个实例在自己机器上跑通
4.1 环境准备与一键运行方式
拿到源码后,不要直接双击运行,而是建议创建虚拟环境。按下面的步骤做,能避免大部分环境冲突。
# 进入项目根目录
cd python100
# 创建虚拟环境
python3 -m venv venv
# 激活虚拟环境(Windows)
venv\\Scripts\\activate
# 激活虚拟环境(macOS/Linux)
source venv/bin/activate
# 安装所有依赖
pip install -r requirements.txt
requirements.txt 里指定了最小版本,比如 requests>=2.25 、 pandas>=1.2 。这些版本都是经过验证的,不要随手升级到刚发布的新大版本,因为某些旧实例可能依赖旧版 API。
运行单个实例时,先看看该实例的 README.md ,里面会写明必需的输入文件格式和示例命令。大多数实例都使用 argparse 设计命令行接口,所以用法基本统一:
python 02_log_parser.py server.log –top 20
如果你在 IDE 里运行,也可以在 main() 上右键选择运行,但需要提前在运行配置里填好参数。一个不熟悉的实例,建议先加 –help 看一下参数定义:
python 03_news_crawler.py –help
4.2 常见问题排查:从"ModuleNotFoundError"到"中文乱码"
这一份源码因为实例数量多,跨平台运行时的坑也特别多。我梳理了五条高频问题,覆盖我自己和身边同事踩过的雷。
现象一: ModuleNotFoundError: No module named 'PyQt5'
原因:虚拟环境里没安装 requirements.txt ,或者安装时用了系统 Python 导致库装到了别的位置。也有的实例单独依赖 pyqt5-tools ,需要额外安装。
解决:先确认激活的是哪个环境, which python 或 pip show pyqt5 看看路径。如果确实没装,跑 pip install -r requirements.txt 。个别 GUI 实例在 macOS 上还需要 brew install tcl-tk ,否则 tkinter 可能缺失。
现象二:爬虫运行时出现 SSL: CERTIFICATE_VERIFY_FAILED
原因:Python 默认验证 SSL 证书,而某些公司的网络代理或自签名证书会导致校验失败。
解决:临时关闭证书验证要谨慎,可以在 requests.get 里加 verify=False ,同时屏蔽警告。但如果是抓取公开数据,更好的做法是更新证书库。最干净的方法是从官方下载并安装 certifi ,然后用 requests.Session 挂载证书。如果只是测试, verify=False 够用,但生产环境绝对不建议。
现象三:用 Excel 打开生成的 CSV 全部糊在一列里
原因:CSV 写入时没有指定 newline='' ,或编码用了 utf-8 而不是 utf-8-sig 。Windows 上 Excel 默认用 GBK 解析,遇到 UTF-8 的逗号分隔符会识别失败。
解决:写入时用 open(filename, 'w', newline='', encoding='utf-8-sig') ,这是源码实例里已经踩平的路。如果你自己写 CSV 脚本,直接抄这个写法。
现象四:GUI 界面在高 DPI 屏幕上显示模糊
原因:Windows 缩放比例不是 100% 时,tkinter 默认不启用自适应缩放。Qt 也需要注意 AA_EnableHighDpiScaling 标志。
解决:tkinter 实例可以在脚本开头加一段声明:
from ctypes import windll
windll.shcore.set_process_dpi_awareness(1)
PyQt5 则需要在创建 QApplication 之前设置 QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True) 。这个坑在笔记本外接显示器时特别明显,我每次都会先补上这段代码。
现象五:运行 05_data_processing 实例时找不到 openpyxl 但明明已安装
原因:pandas 读取 .xlsx 依赖 openpyxl ,读取 .xls 依赖 xlrd 。如果你安装的是新版 pandas,可能不再自动带上 xlrd ,报错信息也不直接提示缺哪个库。
解决:确认文件扩展名。 .xlsx 用 openpyxl , .xls 用 xlrd 。在虚拟环境里分别 pip install openpyxl xlrd 。我建议统一把旧 .xls 文件转换成 .xlsx 再处理,省心。
每条问题都可以在源码的 docs/FAQ.md 里找到对应条目,原整理者把问题描述和解决方法都记录在案,你遇到问题时可以先去那里搜。
5. 二次开发思路:把这些源码改造成自己的项目
5.1 如何挑选和替换模块
拿到一套 100 个实例,不需要全部看,而是按需取样。我的做法是先跑通一个目标实例,然后把它当作"骨架",替换掉内部实现。比如想要一个带进度条的下载工具,可以先从 01_http_downloader 开始,它已经实现了分段下载、断点续传。此时只需要保留 download_chunk 函数,把界面部分换成你自己的 UI 框架。
替换模块的关键在于认准接口。原实例的 main() 和核心业务函数通常只有一个依赖关系,你在复制时尽量保持函数签名不变,这样测试还是原来的输入,不会一改就崩。
改造前后对比表
| news_crawler | 抓新闻列表 | 抓取商品列表 | 修改页面选择器和字段 |
| log_parser | 统计IP | 统计接口耗时 | 换正则、换统计维度 |
| excel_cleaner | 清洗销售表 | 清洗用户信息表 | 修改业务规则列 |
5.2 如何组合多个实例完成一个复杂任务
单个实例解决的是"点"问题,组合起来才能对付"线"问题。比如你能做一个日常自动报表 pipeline:用爬虫实例抓取数据,用数据处理实例清洗结果,再用 GUI 实例生成一个小工具让同事点击运行。这套流程其实就是把一个个 main() 变成可导入的函数。
组合时要避免文件中间态。如果爬虫实例输出 CSV,清洗实例又读入 CSV,那中间文件丢了就很麻烦。建议在你的项目里保持函数级调用,比如 from news_crawler import fetch_page ,直接把请求结果传给下一个函数。机器学习、数据分析领域常说 data pipeline,这里同理。
5.3 我的改造习惯:从复制到抽象的迭代过程
最初我拿到这套源码时,就是复制粘贴,改了路径能跑就算成功。但用了一个月后,我发现每个实例里都有重复的代码片段:解析命令行参数、读文件、写结果。于是我开始把这些片段抽离到一个统一的工具模块,自己的项目因此瘦了一大圈。
我的习惯是:每次要移植一个实例,先老老实实跑通,然后读一遍核心函数,问自己"如果入参变成字典而不是文件路径,我改哪里?" 这能逼着你找到耦合点。接着我会把超时的参数、编码、日志开关改成可配置,而不是硬编码在函数内部。这样实例就从"一次性脚本"变成了"可复用组件"。
特别是爬虫和数据处理这两个领域,配置化是刚需。比如新闻爬虫里的 User-Agent 、请求间隔、超时时间,我都会放到 config.json 或环境变量里,这样在开发、测试、生产环境切换时,不需要改代码逻辑。
从那时起,我每次接手新的源码资源,都强制自己走一遍"跑通实例 → 识别接口 → 抽离公共代码 → 写测试用例"的流程。这套源码让我最初的一周效率翻倍,也让我明白了:真正有用的源码不是用来抄的,而是用来理解设计意图的。希望这些改造思路也能帮到你。
本文还有配套的精品资源,点击获取


