单元 5 · 规范与综合实战 — 预计 90 分钟
综合项目实战
📍 本课路径
- 独立完成完整爬虫项目
- 串联请求、解析、存储全部技能
- 编写健壮的异常处理与日志
🎯 学习节奏:① 看目标 → ② 先思考再动手 → ③ 在运行器写代码 → ④ 失败时按提示重试 → ⑤ 通过后看思路
学完所有章节,是时候串成完整项目了。这一章以「爬取图书榜存 CSV + SQLite」为例走完全流程。
一、需求分析
- 数据源:图书榜列表页(书名、价格)
- 输出:books.csv + books.db
- 约束:守 robots.txt、控频率、出错不中断
二、项目结构
crawler/
├── crawler.py # 主程序
├── books.csv # 产出
└── books.db # 产出
三、可运行:迷你爬虫端到端
下面是一个缩微版全流程,你需要补全三个核心步骤:
import csv, io, sqlite3
from bs4 import BeautifulSoup
html = "<ul class='books'><li class='book'><span class='title'>Python 入门</span><span class='price'>59</span></li><li class='book'><span class='title'>爬虫实战</span><span class='price'>69</span></li><li class='book'><span class='title'>数据分析</span><span class='price'>79</span></li></ul>"
# 步骤 1: 解析提取
# TODO 1: 用 BS4 解析 html,遍历 li.book 收集 title+price 字典列表
soup = BeautifulSoup(html, "lxml")
books = [{
"title": li.select_one(".title").get_text(strip=True),
"price": li.select_one(".price").get_text(strip=True),
} for li in soup.select("li.book")]
# 步骤 2: 存 CSV
# TODO 2: 用 csv.DictWriter 写入 buf(writeheader + writerows)
buf = io.StringIO()
w = csv.DictWriter(buf, fieldnames=["title", "price"])
w.writeheader()
w.writerows(books)
# 步骤 3: 落 SQLite
# TODO 3: 连接内存库,建表,批量插入,SELECT 查询打印
conn = sqlite3.connect(":memory:")
c = conn.cursor()
c.execute("CREATE TABLE book (title TEXT, price TEXT)")
c.executemany("INSERT INTO book VALUES (?, ?)", [(b["title"], b["price"]) for b in books])
print("抓到:", len(books), "本")
print("--- CSV ---")
print(buf.getvalue())
print("--- DB ---")
for row in c.execute("SELECT * FROM book"):
print(row)
conn.close()四、异常处理与日志
import logging, time, random
import requests
logging.basicConfig(filename="crawler.log", level=logging.INFO)
def fetch(url, headers):
for attempt in range(3):
try:
resp = requests.get(url, headers=headers, timeout=5)
resp.raise_for_status()
return resp.text
except requests.exceptions.RequestException:
time.sleep(random.uniform(2, 5))
return None
五、交付清单
- 代码可运行,无硬编码敏感信息
- robots.txt 已检查,频率已控制
- 数据已落 CSV / 数据库
- 日志可回溯,异常有处理
- 合规自检通过
六、小结
- 完整项目 = 需求 → 结构 → 请求/解析/存储 → 异常/日志 → 交付
- 先在内联数据跑通再联网,排错更高效
- 健壮性靠 try/except + 重试 + logging
- 交付前过合规清单,底线更重要