单元 4 · 反爬与动态页面 — 预计 55 分钟
动态页面与 Playwright
📍 本课路径
- 判断页面是否动态渲染
- 使用 Playwright 自动化浏览器
- 等待元素出现并提取数据
🎯 学习节奏:① 看目标 → ② 先思考再动手 → ③ 在运行器写代码 → ④ 失败时按提示重试 → ⑤ 通过后看思路
前面所有解析都假设:数据已经写在 HTML 源码里。但很多网站用 JavaScript 动态生成内容——你「查看源代码」看不到数据,只有浏览器跑完 JS 后才出现。这类页面,requests 抓不到,得上真实浏览器。
一、怎么判断页面是动态的
- 浏览器里能看到数据,但 右键 → 查看网页源代码 搜不到关键词 → 数据靠 JS 注入。
- F12 → Network 里,真正的接口藏在 XHR/Fetch 中(这时优先直接抓接口,见第 9 章)。
- 如果数据既不在源码、也没有独立接口,那就是纯前端渲染,必须上浏览器自动化。
二、Playwright:把浏览器交给代码
Playwright 能启动一个真实(无头)浏览器,像人一样打开页面、等 JS 跑完、再读内容。
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://example.com/list", timeout=30000)
page.wait_for_selector(".book")
html = page.content()
browser.close()
Playwright 需要本地安装,无法在浏览器运行器里执行——请在电脑上跑。
三、等待与交互
page.wait_for_selector(".list") # 等元素出现
page.wait_for_timeout(1000) # 硬等 1 秒(兜底)
page.click(".load-more") # 点击加载更多
四、可运行:解析渲染后的 HTML
Playwright 拿到的 page.content() 和静态页一样用 BS4 解析。补全下面的提取逻辑:
from bs4 import BeautifulSoup
rendered = "<ul class='books'><li class='book'><span class='title'>Python 入门</span></li><li class='book'><span class='title'>爬虫实战</span></li></ul>"
# TODO 1: 用 BeautifulSoup 解析 rendered
soup = BeautifulSoup(rendered, "lxml")
# TODO 2: 遍历 li.book 提取 .title 文本并打印
for li in soup.select("li.book"):
print(li.select_one(".title").get_text(strip=True))五、什么时候才上 Playwright
- 能抓 JSON 接口 → 优先(第 9 章)
- 数据在 HTML 源码 → requests + BS4 足矣
- 只有 JS 渲染才有效据 → 才用 Playwright
六、小结
- 判断动态:源码搜不到 + 无接口 → 需浏览器自动化
- Playwright 流程:launch → goto → wait → content → BS4
- 能用接口/静态就别用 Playwright,重且慢
靶站实战:前往 /practice/level5-dynamic/ 动手练习本课内容。