📖 知识点回顾
page.get()访问网页,page.eles()批量抓元素- 翻页循环 + 判断停止(Day24、Day30)
try/except排障兜底- sqlite3 四步:连接→建表→插入→提交
- 去重:用 SQL 查询避免重复入库
💡 完整闭环 采集(DrissionPage)→ 清洗(处理空值)→ 入库(SQLite)→ 查询验证(SQL)
⚔️ Kata 实战任务(拓展收官项目)
任务需求:
- 导入 sqlite3 和 ChromiumPage、time
- 访问分页列表练习页
- 循环翻页采集列表数据
- 清洗:跳过空文本、去重(入库前用 SQL 判断是否存在)
- 写入 SQLite 数据库
collected.db,建表data - 查询验证入库结果,打印汇总
参考代码
import sqlite3
import time
from DrissionPage import ChromiumPage
# 1. 连接宝库并建表
conn = sqlite3.connect("collected.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS data (id INTEGER PRIMARY KEY, content TEXT UNIQUE)")
print("🏦 已连接数据库 collected.db")
# 2. 打开分页列表练习页
page = ChromiumPage()
page.get("https://the-internet.herokuapp.com/dynamic_content")
print("🌐 已打开分页列表页")
insert_count = 0 # 实际入库条数
# 3. 循环翻页采集并入库
try:
for page_num in range(1, 4):
print(f"\n📄 正在采集第 {page_num} 页……")
# 批量抓取当前页列表元素
items = page.eles(".large-10")
for item in items:
text = item.text.strip()
if not text: # 清洗:跳过空数据
continue
# 入库:UNIQUE约束天然去重,重复内容会报错被跳过
try:
cur.execute("INSERT INTO data (content) VALUES (?)", (text,))
insert_count += 1
except sqlite3.IntegrityError:
pass # 已存在,跳过
conn.commit()
# 翻页
next_btn = page.ele("a:has-text(Next)")
if not next_btn:
print("⏹️ 没有下一页,停止")
break
next_btn.click()
time.sleep(1)
except Exception as e:
print(f"❌ 采集异常:{e}")
# 4. 查询验证入库结果
cur.execute("SELECT COUNT(*) FROM data")
total = cur.fetchone()[0]
cur.execute("SELECT * FROM data")
print("\n🎉 采集完成!本次新增入库", insert_count, "条")
print(f"📚 数据库共 {total} 条记录:")
for row in cur.fetchall():
print(f" {row[0]}. {row[1]}")
conn.close()
print("🔒 宝库已关闭归档")
运行输出(示意):
🏦 已连接数据库 collected.db
🌐 已打开分页列表页
📄 正在采集第 1 页……
📄 正在采集第 2 页……
📄 正在采集第 3 页……
⏹️ 没有下一页,停止
🎉 采集完成!本次新增入库 12 条
📚 数据库共 12 条记录:
1. ...
2. ...
...
🔒 宝库已关闭归档
💡 说明:表里
content TEXT UNIQUE用唯一约束实现自动去重,重复数据重复插入会抛IntegrityError被跳过。跑完后,目录下会生成collected.db文件,可用 SQLite 工具查看。
🧠 思考题
- 代码里
UNIQUE约束和try/except IntegrityError是怎么配合实现 "去重" 的? - 如果要统计 "不同内容各有多少条",SQL 该怎么写?和文件存储比哪个更省事?