单元 3 · 进阶爬取 — 预计 45 分钟
分页与翻页
📍 本课路径
- 识别分页 URL 规律
- 循环遍历所有页面
- 控制请求频率防止误伤
🎯 学习节奏:① 看目标 → ② 先思考再动手 → ③ 在运行器写代码 → ④ 失败时按提示重试 → ⑤ 通过后看思路
单个列表页往往装不下全部数据,网站会用「分页」把它们拆成多页。爬虫要做的,就是找到翻页规律,把每一页都抓回来。
一、找分页 URL 规律
最常见的分页是 ?page=1、?page=2……把页数换成变量即可:
base = "https://books.example.com/list"
for page in range(1, 6): # 1 到 5 页
url = f"{base}?page={page}"
resp = requests.get(url, headers=headers, timeout=5)
# ...解析这一页
有些站点用路径分页(/list/1、/list/2),规律一样,只是拼法不同。先翻两三页,确认「变的是哪一段」。
二、可运行:循环解析多页并汇总
下面模拟 3 页 HTML 数据,你需要补全「逐页解析 + 汇总到一个列表」的逻辑:
from bs4 import BeautifulSoup
pages = [
'''<ul class="books"><li class="book">Python 入门</li><li class="book">爬虫实战</li></ul>''',
'''<ul class="books"><li class="book">数据分析</li><li class="book">算法图解</li></ul>''',
'''<ul class="books"><li class="book">SQL 必知必会</li><li class="book">深度学习</li></ul>''',
]
all_books = []
# TODO: 遍历 pages(用 enumerate 编号),每页 BS4 解析后 extend 进 all_books
for i, html in enumerate(pages, start=1):
soup = BeautifulSoup(html, "lxml")
titles = [li.get_text(strip=True) for li in soup.select("li.book")]
print(f"第 {i} 页抓到 {len(titles)} 本")
all_books.extend(titles)
print("合计:", len(all_books), "本 ->", all_books)三、控制请求频率
翻页意味着短时间内发很多请求,太快会被当成攻击。每页之间 sleep 一下:
import time
for page in range(1, 6):
resp = requests.get(f"{base}?page={page}", timeout=5)
# ...解析
time.sleep(1) # 每秒最多 1 个请求,对服务器友好
四、何时停手
两种常见终止条件:
- 已知总页数:
range(1, total + 1)。 - 未知总页数:解析本页,若「没有数据」或「下一页按钮不存在」就
break。
while True:
resp = requests.get(url, timeout=5)
items = parse(resp.text)
if not items: # 空页,到底了
break
# ...收集
if not has_next_page(resp.text):
break
url = next_page_url(resp.text)
五、小结
- 翻页先找规律:
?page=N还是/page/N,把变的部分参数化。 - 核心是
for/while循环,每页解析后extend进总列表。 - 每页之间
time.sleep控频,避免压垮服务器、也避免被封。 - 未知页数用「空页 / 无下一页」作为终止信号
break。 - 去 Level 2 靶站 实战多页汇总。
靶站实战:前往 /practice/level2-pagination/ 动手练习本课内容。