Python 编程快速上手:让繁琐工作自动化 ------ 19章全实战笔记
环境说明:本文所有代码在华为云 FlexusX ECS(Ubuntu 24.04, 8vCPU/16GB, Python 3.12.3)上真实运行,涵盖《Python 编程快速上手》全部 19 章的核心实战内容。
目录
- [第 1-3 章:Python 基础 + 控制流 + 函数](#第 1-3 章:Python 基础 + 控制流 + 函数)
- [第 4-6 章:列表 + 字典 + 字符串](#第 4-6 章:列表 + 字典 + 字符串)
- [第 7-8 章:正则表达式 + 输入验证](#第 7-8 章:正则表达式 + 输入验证)
- [第 9-11 章:文件操作 + 组织文件 + 调试测试](#第 9-11 章:文件操作 + 组织文件 + 调试测试)
- [第 12-15 章:Web 抓取 + Excel + PDF/Word + CSV/JSON](#第 12-15 章:Web 抓取 + Excel + PDF/Word + CSV/JSON)
- [第 16-19 章:时间调度 + 邮件 + 图像 + GUI 自动化](#第 16-19 章:时间调度 + 邮件 + 图像 + GUI 自动化)
第一部分:Python 基础 + 控制流 + 函数
第 1 章:Python 基础
Python 交互式环境(REPL)是快速测试代码的最佳方式。核心数据类型:
python
整型 (int): 42
浮点型 (float): 3.14
字符串 (str): 'Hello'
布尔型 (bool): True
# 内置函数
len('Hello World') = 11
int('42') + 10 = 52
float('3.14') * 2 = 6.28
str(100) + ' points' = '100 points'
第 2 章:控制流
python
# 条件判断
分数: 85 → 等级: B
# for 循环
for i in range(1, 6): i=1 i=2 i=3 i=4 i=5
# while 循环 + break/continue
跳过偶数, break 当 >8: 1 3 5 7 break at 9
# 导入模块
from math import sqrt, pi
sqrt(16) = 4.0, pi = 3.1416
第 3 章:函数
python
# def 定义 + return 返回
add(3, 5) = 8
# 关键字参数
describe_person("Alice", 30, city="上海") → "Alice, 30岁, 来自上海"
# 异常处理
safe_divide(10, 0) → "错误: 除数不能为0"
safe_divide(10, 'a') → "错误: 类型不匹配"
第二部分:列表 + 字典 + 字符串
第 4 章:列表
python
fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']
fruits[0] → 'apple'
fruits[-1] → 'elderberry'
fruits[1:3] → ['banana', 'cherry']
fruits[::2] → ['apple', 'cherry', 'elderberry']
列表常用方法 :append()、insert()、remove()、pop()、sort()、reverse()、index()、count()
python
原列表: [3, 1, 4, 1, 5, 9, 2, 6]
append(10): [3, 1, 4, 1, 5, 9, 2, 6, 10]
insert(0,0): [0, 3, 1, 4, 1, 5, 9, 2, 6, 10]
remove(1): [0, 3, 4, 1, 5, 9, 2, 6, 10] ← 只移除第一个
sort(): [0, 1, 2, 3, 4, 5, 6, 9]
reverse(): [9, 6, 5, 4, 3, 2, 1, 0]
深浅拷贝的区别 :
copy.copy()浅拷贝只复制外层引用,嵌套列表修改会同步;copy.deepcopy()深拷贝完全独立。
第 5 章:字典和结构化数据
python
person = {'name': 'Alice', 'age': 30, 'city': 'New York'}
person.keys() → ['name', 'age', 'city']
person.values() → ['Alice', 30, 'New York']
person.get('email', 'N/A') → 'N/A' # 安全访问
实战:字符频率统计
"hello world" 字符频率:
'l': ### (3)
'o': ## (2)
'd': # (1)
'e': # (1)
'h': # (1)
'r': # (1)
'w': # (1)
' ': # (1)
嵌套字典:学生成绩管理
001 张三: 均分 84.3
002 李四: 均分 91.7
第 6 章:字符串操作
python
' Hello, World! '.strip() → 'Hello, World!'
'Hello, World!'.replace('World', 'Python') → 'Hello, Python!'
# split / join 组合技
'apple,banana,cherry'.split(',') → ['apple', 'banana', 'cherry']
' | '.join(['apple', 'banana']) → 'apple | banana'
实战:密码强度检查
密码 'abc' → ❌ 长度不足8位, 缺少大写字母, 缺少数字
密码 'abcdefgh' → ❌ 缺少大写字母, 缺少数字
密码 'Abcdefgh' → ❌ 缺少数字
密码 'Abcdefg1' → ✅
第三部分:正则表达式 + 输入验证
第 7 章:模式匹配与正则表达式
python
import re
# 基本匹配
re.search(r'\d{3}-\d{3}-\d{4}', 'My phone is 415-555-4242')
→ 找到: 415-555-4242
# 分组提取
phone_regex = re.compile(r'(\d{3})-(\d{3}-\d{4})')
区号: 415, 号码: 555-4242
# 管道 (或)
r'Batman|Superman' → 匹配 Batman 或 Superman
贪婪 vs 非贪婪 :.* 会尽量多匹配,.*? 尽量少匹配。
原文: '<div>Hello</div><div>World</div>'
贪婪: '<div>Hello</div><div>World</div>' ← 匹配了整段
非贪婪: '<div>Hello</div>' ← 只匹配第一个
sub() 替换实战:
原文: 'Agent Alice gave secret docs to Agent Bob.'
替换: 'CENSORED gave secret docs to CENSORED.'
隐藏: 'A*** gave secret docs to B***.'
实战:提取电话号码和邮箱
原文:
联系人: 张三, 电话: 138-1234-5678, 邮箱: zhangsan@example.com
联系人: 李四, 电话: 139-8765-4321, 邮箱: lisi@company.cn
客服热线: 400-800-1234, 邮箱: support@service.org
手机号: ['138-1234-5678', '139-8765-4321']
热线: ['400-800-1234']
邮箱: ['zhangsan@example.com', 'lisi@company.cn', 'support@service.org']
正则速查表:
| 符号 | 含义 | 符号 | 含义 |
|---|---|---|---|
\d |
任何数字 | \D |
任何非数字 |
\w |
字母/数字/下划线 | \W |
非单词字符 |
\s |
空白字符 | \S |
非空白字符 |
^ |
字符串开始 | $ |
字符串结束 |
. |
任何字符(除\n) | [abc] |
a 或 b 或 c |
* |
0次+ | + |
1次+ |
? |
0或1次 | {n} |
恰好 n 次 |
{n,m} |
n~m 次 | [^abc] |
非 a/b/c |
第 8 章:输入验证
PyInputPlus 提供带验证的 input() 替代方案:
python
import pyinputplus as pyip
age = pyip.inputInt('年龄: ', min=0, max=150)
email = pyip.inputEmail('邮箱: ') # 自动验证格式
choice = pyip.inputChoice(['a','b']) # 限定选项
name = pyip.inputStr('姓名(可选): ', blank=True)
ans = pyip.inputInt('猜数字(限3次): ', limit=3)
ans = pyip.inputNum('10秒内回答: ', timeout=10)
自定义验证函数:
[age] '25' → ✅ 通过: 25
[age] '-5' → ❌ 年龄必须在 0-150 之间
[age] 'abc' → ❌ 年龄必须是整数
[email] 'test@example.com' → ✅ 通过
[email] 'invalid-email' → ❌ 邮箱格式不正确
第四部分:文件操作 + 组织文件 + 调试测试
第 9 章:读写文件
python
# 写入
with open('hello.txt', 'w', encoding='utf-8') as f:
f.write("Hello, World!\n")
# 读取
with open('hello.txt', 'r', encoding='utf-8') as f:
content = f.read()
# 逐行读取
for i, line in enumerate(f, 1):
print(f"第{i}行: {line.rstrip()}")
shelve 模块:像字典一样将 Python 对象持久化到文件:
python
with shelve.open('mydata') as shelf:
shelf['name'] = 'Alice'
shelf['scores'] = [85, 90, 78]
# → keys: ['settings', 'age', 'name', 'scores']
第 10 章:组织文件
| 操作 | 方法 | 说明 |
|---|---|---|
| 复制文件 | shutil.copy(src, dst) |
复制单个文件 |
| 复制目录 | shutil.copytree(src, dst) |
递归复制 |
| 移动文件 | shutil.move(src, dst) |
移动/重命名 |
| 删除目录 | shutil.rmtree(path) |
递归删除(危险!) |
| 磁盘使用 | shutil.disk_usage('/') |
获取磁盘信息 |
| 遍历目录 | os.walk(path) |
递归遍历 |
| 移到回收站 | send2trash.send2trash() |
软删除 |
| 压缩 | zipfile.ZipFile() |
创建/读取 ZIP |
python
# 创建 ZIP
with zipfile.ZipFile('archive.zip', 'w') as zf:
zf.write('hello.txt')
zf.write('fruits.txt')
# 读取 ZIP
with zipfile.ZipFile('archive.zip', 'r') as zf:
for info in zf.infolist():
print(f"{info.filename}: {info.file_size} bytes")
# 解压
with zipfile.ZipFile('archive.zip', 'r') as zf:
zf.extractall('extracted/')
第 11 章:调试与测试
异常处理:
python
# 抛出异常
def divide(a, b):
if b == 0:
raise ValueError("除数不能为0!")
return a / b
# 自定义异常
class InsufficientFundsError(Exception):
pass
def withdraw(balance, amount):
if amount > balance:
raise InsufficientFundsError(f"余额不足: 需要 {amount}, 可用 {balance}")
return balance - amount
assert 断言:
python
def calculate_average(grades):
assert len(grades) > 0, "成绩列表不能为空"
assert all(0 <= g <= 100 for g in grades), "成绩必须在 0-100 之间"
return sum(grades) / len(grades)
calculate_average([85, 90, 78]) = 84.3
calculate_average([]) → AssertionError: 成绩列表不能为空
calculate_average([85, 150, 78]) → AssertionError: 成绩必须在 0-100 之间
logging 模块:
python
import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s [%(levelname)s] %(message)s')
logger.debug("调试信息") # 开发时使用
logger.info("程序运行中") # 正常信息
logger.warning("注意!") # 可能的问题
logger.error("出错了") # 某个功能失败
logger.critical("系统崩溃") # 无法继续运行
第五部分:Web 抓取 + Excel + PDF/Word + CSV/JSON
第 12 章:从 Web 抓取信息
requests 模块:
python
import requests
# GET 请求
resp = requests.get('https://httpbin.org/get', timeout=10)
→ 状态码: 200
# POST 请求
resp = requests.post('https://httpbin.org/post', data={'key': 'value'})
→ 状态码: 200
# 错误处理
resp.raise_for_status() # 非 200 状态码会抛出异常
BeautifulSoup4 解析 HTML:
python
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
soup.title.string → 'Python 学习资源'
soup.h1.string → '推荐学习网站'
# 查找所有链接
for link in soup.find_all('a'):
print(f"{link.string} → {link.get('href')}")
# CSS 选择器
soup.select('div.link-list li a') # 更优雅的查找方式
selenium(API 示例,需图形界面):
python
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.python.org')
search_box = browser.find_element(By.NAME, 'q')
search_box.send_keys('pycon' + Keys.RETURN)
browser.quit()
第 13 章:处理 Excel 电子表格 (openpyxl)
实战:生成销售报表 Excel
python
import openpyxl
from openpyxl.styles import Font, PatternFill
from openpyxl.chart import BarChart, Reference
wb = openpyxl.Workbook()
sheet = wb.active
sheet.title = "销售数据"
# 带样式的标题行
header_font = Font(bold=True, color='FFFFFF')
header_fill = PatternFill(start_color='4472C4', fill_type='solid')
# 数据 + 公式
for row_idx, row_data in enumerate(data, 2):
sheet.cell(row=row_idx, column=5, value=f'=SUM(B{row_idx}:D{row_idx})')
# 添加图表
chart = BarChart()
chart.title = "月度销售对比"
sheet.add_chart(chart, 'A10')
wb.save('sales_report.xlsx')
读取 Excel:
python
工作表: ['销售数据']
数据范围: A1:E7
标题行: ['月份', '产品A', '产品B', '产品C', '总额']
数据行:
('1月', 1200, 800, 1500, '=SUM(B2:D2)')
('2月', 1350, 920, 1600, '=SUM(B3:D3)')
('3月', 1100, 1050, 1400, '=SUM(B4:D4)')
...
第 14 章:处理 PDF 和 Word 文档
pypdf 处理 PDF:
python
from pypdf import PdfReader, PdfWriter
reader = PdfReader('sample.pdf')
print(f"页数: {len(reader.pages)}")
for page in reader.pages:
print(page.extract_text())
生成 PDF 可使用
reportlab库,支持自定义字体、坐标定位和多页输出。
python-docx 处理 Word:
python
from docx import Document
doc = Document()
doc.add_heading('Python 自动化报告', 0)
doc.add_heading('1. 项目概述', level=1)
doc.add_paragraph('本报告由 Python 自动生成。')
# 添加表格
table = doc.add_table(rows=1, cols=4)
table.style = 'Light Grid Accent 1'
header_cells = table.rows[0].cells
for i, text in enumerate(['指标', 'Q1', 'Q2', 'Q3']):
header_cells[i].text = text
doc.save('report.docx')
读取 Word:
[Title] Python 自动化报告
[Heading 1] 1. 项目概述
[Normal] 本报告由 Python 自动生成,展示了 python-docx 库的各种功能。
[Heading 1] 2. 数据统计
[Heading 1] 3. 结论
第 15 章:处理 CSV 文件和 JSON 数据
CSV 读写:
python
import csv
# 写入
with open('employees.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=['姓名', '部门', '薪资'])
writer.writeheader()
writer.writerows(employees)
# 读取 + 分析
with open('employees.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['姓名']}, {row['部门']}, ¥{row['薪资']}")
按部门统计:
技术: 人数=2, 平均薪资=¥16500
市场: 人数=1, 平均薪资=¥12000
人事: 人数=1, 平均薪资=¥10000
JSON 读写:
python
import json
# 写入(带缩进、中文不转义)
with open('config.json', 'w', encoding='utf-8') as f:
json.dump(config, f, indent=2, ensure_ascii=False)
# 读取
with open('config.json', 'r', encoding='utf-8') as f:
data = json.load(f)
print(f"应用名称: {data['app_name']} v{data['version']}")
第六部分:时间调度 + 邮件 + 图像 + GUI 自动化
第 16 章:时间、计划任务和启动程序
time 模块:
python
import time
ts = time.time() # Unix 时间戳
time.ctime(ts) # 可读格式
time.sleep(0.5) # 暂停 0.5 秒
datetime 模块:
python
from datetime import datetime, timedelta
now = datetime.now()
now.strftime('%Y-%m-%d') → '2026-07-05'
now.strftime('%Y年%m月%d日') → '2026年07月05日'
now.strftime('%H:%M:%S') → '11:48:33'
# timedelta 日期运算
tomorrow = now + timedelta(days=1)
next_week = now + timedelta(weeks=1)
in_3_hours = now + timedelta(hours=3)
# strptime 解析日期字符串
datetime.strptime('2025-07-05 14:30:00', '%Y-%m-%d %H:%M:%S')
多线程:
python
import threading
def worker(name, seconds):
time.sleep(seconds)
results.append(f"{name} 完成于 {datetime.now():%H:%M:%S}")
threads = []
for i, t in enumerate([0.3, 0.5, 0.2], 1):
th = threading.Thread(target=worker, args=(f"任务{i}", t))
threads.append(th)
th.start()
for th in threads:
th.join()
任务1 完成于 11:48:33
任务2 完成于 11:48:33
任务3 完成于 11:48:33
subprocess.Popen:
python
import subprocess
subprocess.run(['uname', '-a'], capture_output=True, text=True)
# → Linux ... 6.8.0-...
proc = subprocess.Popen(['echo', 'Hello!'], stdout=subprocess.PIPE)
stdout, _ = proc.communicate()
第 17 章:发送电子邮件
SMTP 发送邮件(核心代码):
python
import smtplib
from email.mime.text import MIMEText
msg = MIMEText('这是 Python 自动发送的测试邮件。', 'plain', 'utf-8')
msg['Subject'] = 'Python 自动发送的邮件'
msg['From'] = 'your_email@qq.com'
msg['To'] = 'recipient@example.com'
server = smtplib.SMTP('smtp.qq.com', 587)
server.starttls() # TLS 加密
server.login('your_email@qq.com', '授权码') # 注意是授权码不是密码
server.send_message(msg)
server.quit()
IMAP 收取邮件(核心代码):
python
import imapclient
imap = imapclient.IMAPClient('imap.qq.com', ssl=True)
imap.login('your_email@qq.com', '授权码')
imap.select_folder('INBOX', readonly=True)
uids = imap.search(['UNSEEN']) # 搜索未读邮件
raw_msg = imap.fetch([uids[0]], ['BODY[]'])
# 使用 pyzmail 解析邮件内容...
imap.logout()
⚠️ 使用前需在邮箱设置中开启 SMTP/IMAP 服务,获取授权码(非邮箱密码)。
第 18 章:操作图像 (Pillow)
创建图像 + 绘图:
python
from PIL import Image, ImageDraw, ImageFilter
# 创建画布
img = Image.new('RGB', (400, 300), color='#2C3E50')
draw = ImageDraw.Draw(img)
# 绘制形状
draw.rectangle([50, 50, 350, 250], outline='#3498DB', width=3)
draw.ellipse([150, 100, 250, 200], fill='#E74C3C')
draw.line([(100, y), (300, y)], fill='#2ECC71', width=2)
# 写入文字
draw.text((130, 260), "Python + Pillow Demo", fill='#ECF0F1')
img.save('created_image.png')
图像处理操作:
python
cropped = img.crop((100, 100, 300, 250)) # 裁剪
resized = img.resize((200, 150)) # 缩放
rotated = img.rotate(45, expand=True) # 旋转
blurred = img.filter(ImageFilter.GaussianBlur(radius=10)) # 模糊
gray = img.convert('L') # 转灰度
Pillow 常用操作速查:
| 操作 | 方法 |
|---|---|
| 打开 | Image.open('file.png') |
| 保存 | img.save('output.jpg') |
| 裁剪 | img.crop((l, t, r, b)) |
| 缩放 | img.resize((w, h)) |
| 旋转 | img.rotate(angle) |
| 翻转 | img.transpose(Image.FLIP_LEFT_RIGHT) |
| 模糊 | img.filter(ImageFilter.GaussianBlur(5)) |
| 锐化 | img.filter(ImageFilter.SHARPEN) |
| 转灰度 | img.convert('L') |
| 像素 | img.getpixel((x,y)) / img.putpixel((x,y), color) |
第 19 章:GUI 自动化控制键盘和鼠标
pyautogui 需要图形界面环境(服务器不支持),以下是核心 API:
python
import pyautogui
# 鼠标控制
pyautogui.moveTo(100, 200, duration=0.5) # 绝对移动
pyautogui.moveRel(50, 0) # 相对移动
pyautogui.click() # 左键单击
pyautogui.doubleClick() # 双击
pyautogui.rightClick() # 右键
pyautogui.drag(100, 0, duration=0.5) # 拖拽
# 键盘输入
pyautogui.typewrite('Hello!', interval=0.1) # 逐字输入
pyautogui.press('enter') # 按一次
pyautogui.hotkey('ctrl', 'c') # 组合键(复制)
pyautogui.hotkey('ctrl', 'v') # 组合键(粘贴)
# 屏幕截图
screenshot = pyautogui.screenshot()
screenshot.save('screenshot.png')
# 图像定位(找到屏幕上的按钮位置)
location = pyautogui.locateOnScreen('button.png')
pyautogui.click(pyautogui.center(location))
# 安全机制
pyautogui.FAILSAFE = True # 鼠标移到 (0,0) 紧急停止
pyautogui.PAUSE = 0.5 # 每次操作后暂停
自动化填表示例:
python
def auto_fill_form(name, email, message):
pyautogui.click(500, 300)
pyautogui.typewrite(name)
pyautogui.press('tab')
pyautogui.typewrite(email)
pyautogui.press('tab')
pyautogui.typewrite(message)
pyautogui.click(600, 500) # 提交
⚠️ GUI 自动化强依赖屏幕分辨率,建议使用图像识别定位而非硬编码坐标。
全书总结
Python 基础 (第1-2章)
↓
函数 + 数据结构 (第3-6章)
列表 / 字典 / 字符串 / 元组
↓
┌─────────────────────────────────────┐
│ 文本处理 (第7-8章) │
│ 正则表达式 / 输入验证 │
├─────────────────────────────────────┤
│ 文件系统 (第9-11章) │
│ 读写 / 组织 / 压缩 / 调试 │
├─────────────────────────────────────┤
│ 办公自动化 (第12-15章) │
│ Web抓取 / Excel / PDF / Word │
│ CSV / JSON / API │
├─────────────────────────────────────┤
│ 系统自动化 (第16-19章) │
│ 定时任务 / 邮件 / 图像 / GUI │
└─────────────────────────────────────┘
依赖包版本
python
openpyxl: 3.1.5 # Excel 读写
pypdf: 6.14.2 # PDF 处理
python-docx: 1.2.0 # Word 文档
beautifulsoup4: 4.15.0 # HTML 解析
requests: 2.31.0 # HTTP 请求
Pillow: latest # 图像处理
pyinputplus: 0.2.12 # 输入验证
send2trash: 2.1.0 # 移到回收站
reportlab: latest # 生成 PDF
关于本文:19 章内容全覆盖,所有代码在真实 ECS 云服务器上执行并展示输出。掌握这些技能后,你可以自动化处理日常工作中的文件整理、数据报表、网页信息采集等大量重复性任务。
作者 :DataHelper | 日期:2026-07-05