Python爬虫零基础入门【第七章:动态页面入门(Playwright)·第1节】Playwright 第一次:打开页面、等待元素、拿到渲染后 HTML!

🔥本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~持续更新中!!

全文目录:

    • [🌟 开篇语](#🌟 开篇语)
      • [📚 上期回顾](#📚 上期回顾)
      • [🎯 本篇目标](#🎯 本篇目标)
      • [💡 为什么需要 Playwright?](#💡 为什么需要 Playwright?)
      • [🔧 Playwright 是什么?](#🔧 Playwright 是什么?)
      • [🛠️ 安装 Playwright](#🛠️ 安装 Playwright)
      • [📖 基础操作:打开页面](#📖 基础操作:打开页面)
      • [⏳ 核心难点:等待策略](#⏳ 核心难点:等待策略)
        • [策略 1:等待页面加载完成(load)](#策略 1:等待页面加载完成(load))
        • [策略 2:等待网络空闲(networkidle)](#策略 2:等待网络空闲(networkidle))
        • [策略 3:等待特定元素出现](#策略 3:等待特定元素出现)
        • [策略 4:等待固定时间(不推荐)](#策略 4:等待固定时间(不推荐))
      • [📸 实战:截图 + HTML dump](#📸 实战:截图 + HTML dump)
      • [🎨 调试技巧](#🎨 调试技巧)
        • [技巧 1:有头模式 + 慢动作](#技巧 1:有头模式 + 慢动作)
        • [技巧 2:截图是最好的调试工具](#技巧 2:截图是最好的调试工具)
        • [技巧 3:打印 HTML 长度判断](#技巧 3:打印 HTML 长度判断)
      • [⚠️ 新手常见坑](#⚠️ 新手常见坑)
        • [坑 1:没有等待就提取内容](#坑 1:没有等待就提取内容)
        • [坑 2:超时设置不合理](#坑 2:超时设置不合理)
        • [坑 3:忘记关闭浏览器](#坑 3:忘记关闭浏览器)
      • [📊 性能优化](#📊 性能优化)
        • [优化 1:禁用图片/CSS(提速)](#优化 1:禁用图片/CSS(提速))
        • [优化 2:复用浏览器实例](#优化 2:复用浏览器实例)
      • [🎯 下期预告](#🎯 下期预告)
    • [🌟 文末](#🌟 文末)
      • [📌 专栏持续更新中|建议收藏 + 订阅](#📌 专栏持续更新中|建议收藏 + 订阅)
      • [✅ 互动征集](#✅ 互动征集)

🌟 开篇语

哈喽,各位小伙伴们你们好呀~我是【喵手】。

运营社区: C站 / 掘金 / 腾讯云 / 阿里云 / 华为云 / 51CTO

欢迎大家常来逛逛,一起学习,一起进步~🌟

我长期专注 Python 爬虫工程化实战 ,主理专栏 👉 《Python爬虫实战》:从采集策略反爬对抗 ,从数据清洗分布式调度 ,持续输出可复用的方法论与可落地案例。内容主打一个"能跑、能用、能扩展 ",让数据价值真正做到------抓得到、洗得净、用得上

📌 专栏食用指南(建议收藏)

  • ✅ 入门基础:环境搭建 / 请求与解析 / 数据落库
  • ✅ 进阶提升:登录鉴权 / 动态渲染 / 反爬对抗
  • ✅ 工程实战:异步并发 / 分布式调度 / 监控与容错
  • ✅ 项目落地:数据治理 / 可视化分析 / 场景化应用

📣 专栏推广时间 :如果你想系统学爬虫,而不是碎片化东拼西凑,欢迎订阅/关注专栏《Python爬虫实战》

订阅后更新会优先推送,按目录学习更高效~

📚 上期回顾

恭喜你完成第 6 章!现在你的爬虫已经有了"增量采集"、"断点续爬"、"幂等去重"三大杀器。对于普通的静态网站,你已经游刃有余了。

但真实世界总有新挑战:你打开浏览器能看到商品列表,用 requests.get() 却只拿到一个空壳 HTML;你在页面上能点击"加载更多",代码里却找不到下一页的 URL。

这不是你的问题,而是你遇到了动态渲染网站------数据藏在 JavaScript 里,必须等浏览器执行完才能看到。😤

今天,我们就用 Playwright 来破局!

🎯 本篇目标

看完这篇,你能做到:

  1. 理解动态渲染原理(为什么 requests 抓不到)
  2. 安装并启动 Playwright(自动化浏览器)
  3. 打开页面并等待加载(等待策略很关键)
  4. 提取渲染后的 HTML(截图 + HTML dump)

验收标准:**用 Playwright 打开一个动态网站,保存截图和完

💡 为什么需要 Playwright?

场景对比

静态网站(requests 能搞定):

json 复制代码
浏览器请求 → 服务器返回完整 HTML → 直接展示

requests.get() 拿到的就是最终页面。

动态网站(requests 无能为力):

json 复制代码
浏览器请求 → 服务器返回空壳 HTML + JS 代码
          ↓
       浏览器执行 JS
          ↓
       发送 Ajax 请求获取数据
          ↓
       JS 把数据渲染到页面

requests.get() 只能拿到空壳,看不到真正的数据。

真实案例

打开某电商网站的商品列表:

浏览器看到的:

html 复制代码
<div class="product-list">
  <div class="item">商品A - ¥99</div>
  <div class="item">商品B - ¥199</div>
  ...
</div>

requests 拿到的:

html 复制代码
<div class="product-list">
  <!-- 数据将由 app.js 渲染 -->
</div>
<script src="app.js"></script>

数据在 app.js 里,必须等浏览器执行才能出现!

🔧 Playwright 是什么?

Playwright 是微软开发的自动化测试工具,但我们拿来做爬虫刚刚好。

核心能力:

  • ✅ 控制真实浏览器(Chrome/Firefox/Safari)
  • ✅ 等待 JavaScript 执行完成
  • ✅ 模拟用户操作(点击、滚动、输入)
  • ✅ 截图、录屏、拦截网络请求

类似工具对比:

工具 优点 缺点
Selenium 老牌稳定 速度慢、API 繁琐
Playwright 快、现代、API 友好 社区相对小
Puppeteer 轻量 只支持 Chrome

新手推荐 Playwright,生态成熟且文档清晰。👍

🛠️ 安装 Playwright

第一步:安装 Python 库
bash 复制代码
pip install playwright
第二步:安装浏览器

Playwright 需要下载浏览器驱动(首次使用):

bash 复制代码
playwright install chromium

这会下载约 300MB 的 Chromium 浏览器(和 Chrome 一样的内核)。

也可以安装其他浏览器:

bash 复制代码
playwright install firefox
playwright install webkit  # Safari 内核
验证安装
python 复制代码
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)  # 有头模式,能看到浏览器
    page = browser.new_page()
    page.goto('https://www.baidu.com')
    print(f"✅ 页面标题:{page.title()}")
    browser.close()

如果能看到浏览器弹出并打开百度,说明安装成功!🎉

📖 基础操作:打开页面

最简单的例子
python 复制代码
from playwright.sync_api import sync_playwright

def crawl_with_playwright(url):
    """用 Playwright 打开页面"""
    with sync_playwright() as p:
        # 1. 启动浏览器
        browser = p.chromium.launch(headless=True)  # headless=True 无界面运行
        
        # 2. 创建新页面(标签页)
        page = browser.new_page()
        
        # 3. 打开目标 URL
        page.goto(url)
        
        # 4. 获取页面标题
        title = page.title()
        print(f"📄 页面标题:{title}")
        
        # 5. 关闭浏览器
        browser.close()

# 使用
crawl_with_playwright('https://example.com')
代码解析
python 复制代码
# headless=True  # 无头模式(不显示浏览器窗口,适合服务器)
# headless=False # 有头模式(显示浏览器,适合调试)

browser = p.chromium.launch(
    headless=True,
    slow_mo=100  # 每个操作延迟 100ms(方便观察,调试时用)
)

⏳ 核心难点:等待策略

动态网站最大的坑就是加载时机不确定。你刚打开页面,数据可能还没渲染出来,就开始提取内容------结果一片空白。

Playwright 提供了多种等待策略:

策略 1:等待页面加载完成(load)
python 复制代码
page.goto(url, wait_until='load')  # 等待 load 事件(默认)

适用场景:传统网站,数据在 HTML 里。

缺点:Ajax 请求可能还在进行中。

策略 2:等待网络空闲(networkidle)
python 复制代码
page.goto(url, wait_until='networkidle')  # 等待网络请求结束

适用场景:单页应用(SPA),数据通过 Ajax 加载。

推荐用这个!

策略 3:等待特定元素出现
python 复制代码
page.goto(url)
page.wait_for_selector('.product-list')  # 等待商⭐⭐⭐
策略 4:等待固定时间(不推荐)
python 复制代码
import time

page.goto(url)
time.sleep(3)  # 硬等 3 秒

缺点:不灵活,可能等不够或浪费时间。

仅用于快速测试,生产环境不要用!

📸 实战:截图 + HTML dump

完整示例
python 复制代码
from playwright.sync_api import sync_playwright
from pathlib import Path
from datetime import datetime

class PlaywrightSpider:
    """基于 Playwright 的爬虫基类"""
    
    def __init__(self, headless=True):
        self.headless = headless
        self.output_dir = Path('output')
        self.output_dir.mkdir(exist_ok=True)
    
    def crawl_page(self, url, wait_selector=None):
        """
        采集页面
        
        Args:
            url: 目标 URL
            wait_selector: 等待的 CSS 选择器(可选)
        
        Returns:
            dict: {html, screenshot_path}
        """
        with sync_playwright() as p:
            browser = p.chromium.launch(headless=self.headless)
            page = browser.new_page()
            
            print(f"🔍 正 打开页面(等待网络空闲)
            page.goto(url, wait_until='networkidle', timeout=30000)
            
            # 如果指定了等待元素,额外等待
            if wait_selector:
                print(f"⏳ 等待元素出现:{wait_selector}")
                page.wait_for_selector(wait_selector, timeout=10000)
            
            # 生成文件名(带时间戳)
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            
            # 保存截图
            screenshot_path = self.output_dir / f"screenshot_{timestamp}.png"
            page.screenshot(path=str(screenshot_path), full_page=True)
            print(f"📸 截图已保存:{screenshot_path}")
            
            # 获取渲染后的 HTML
            html = page.content()
            
            # 保存 HTML
            html_path = self.output_dir / f"page_{timestamp}.html"
            html_path.write_text(html, encoding='utf-8')
            print(f"📄 HTML 已保存:{html_path}")
            
            browser.close()
            
            return {
                'html': html,
                'screenshot_path': str(screenshot_path),
                'html_path': str(html_path)
            }

# 使用示态网站
    result = spider.crawl_page(
        url='https://spa.example.com/products',
        wait_selector='.product-list'  # 等待商品列表出现
    )
    
    print(f"\n✅ 采集完成!")
    print(f"   HTML 长度:{len(result['html'])} 字符")
    print(f"   截图路径:{result['screenshot_path']}")

🎨 调试技巧

技巧 1:有头模式 + 慢动作
python 复制代码
browser = p.chromium.launch(
    headless=False,  # 显示浏览器
    slow_mo=500      # 每个操作延迟 500ms
)

你能看到浏览器的每一步操作,方便排查问题。

技巧 2:截图是最好的调试工具

不确定页面加载到哪一步?截个图看看:

python 复制代码
page.screenshot(path='debug.png')
print("📸 调试截图已保存,去看看加载成功了吗")
技巧 3:打印 HTML 长度判断
python 复制代码
html = page.content()
print(f"📊 HTML 长度:{len(html)} 字符")

# 如果长度太短(如 < 1000),说明加载失败
if len(html) < 1000:
    print("⚠️ 页面可能没加载完,检查等待策略")

⚠️ 新手常见坑

坑 1:没有等待就提取内容

现象HTML 是空的或不完整。

原因:页面还在加载,JS 还没执行完。

解决:

python 复制代码
# ❌ 错误
page.goto(url)
html = page.content()  # 可能太早了

# ✅ 正确
page.goto(url, wait_until='networkidle')
page.wait_for_selector('.data-container')  # 双保险
html = page.content()
坑 2:超时设置不合理

现象:程序卡住不动,或者报 TimeoutError

原因:网络慢或页面加载慢。

解决:

python 复制代码
# 调局超时
page.set_default_timeout(60000)  # 60 秒

# 或者针对单个操作
page.goto(url, timeout=60000)
page.wait_for_selector('.content', timeout=30000)
坑 3:忘记关闭浏览器

现象:内存占用越来越高,浏览器进程越来越多。

解决:

python 复制代码
# ❌ 忘记关闭
browser = p.chromium.launch()
page = browser.new_page()
# ... 采集完就跑了,浏览器还开着

# ✅ 用 with 语句自动管理
with sync_playwright() as p:
    browser = p.chromium.launch()
    # ... 代码块结束自动关闭

或者手动:

python 复制代码
try:
    browser = p.chromium.launch()
    # ... 采集逻辑
finally:
    browser.close()  # 确保关闭

📊 性能优化

优化 1:禁用图片/CSS(提速)

如果只要数据不要样式,可以禁用资源加载:

python 复制代码
context = browser.new_context()
page = context.new_page()

# 拦截请求,屏蔽图片和样式
page.route("**/*.{png,jpg,jpeg,gif,svg,css}", lambda route: route.abort())

page.goto(url)

速度能提升 30%-50%

优化 2:复用浏览器实例

不要每次采集都启动新浏览器,太慢了:

python 复制代码
class PlaywrightSpider:
    def __init__(self):
        self.playwright = sync_playwright().start()
        self.browser = self.playwright.chromium.launch(headless=True)
    
    def crawl(self, url):
        page = self.browser.new_page()  # 复用浏览器,只开新标签
        page.goto(url)
        html = page.content()
        page.close()
        return html
    
    def __del__(self):
        self.pip install + playwright install)
  1. 打开页面(goto + 等待策略)
  2. 等待加载(networkidle + wait_for_selector)
  3. 保存结果(截图 + HTML dump)

记住核心原则:等待策略很关键,截图是最好的调试工具。遇到问题先截个图,90% 的情况能看出问题在哪。

🎯 下期预告

今天我们学会了"打开页面",但真实场景往往更复杂:商品列表有 200 条,需要点击"加载更多"按钮 10 次;新闻网站要滚动到底部才会触发下一页加载。

下一篇《动态列表:滚动加载/点击翻页(通用套路)》,我们会搞定滚动翻页点击翻页两大经典场景,让你能采集任何动态列表!

验收作业:用 Playwright 打开一个动态网站(如某电商或新闻站),保存截图和 HTML。把文件发我看看!加油!

🌟 文末

好啦~以上就是本期 《Python爬虫实战》的全部内容啦!如果你在实践过程中遇到任何疑问,欢迎在评论区留言交流,我看到都会尽量回复~咱们下期见!

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦~
三连就是对我写作道路上最好的鼓励与支持! ❤️🔥

📌 专栏持续更新中|建议收藏 + 订阅

专栏 👉 《Python爬虫实战》,我会按照"入门 → 进阶 → 工程化 → 项目落地"的路线持续更新,争取让每一篇都做到:

✅ 讲得清楚(原理)|✅ 跑得起来(代码)|✅ 用得上(场景)|✅ 扛得住(工程化)

📣 想系统提升的小伙伴:强烈建议先订阅专栏,再按目录顺序学习,效率会高很多~

✅ 互动征集

想让我把【某站点/某反爬/某验证码/某分布式方案】写成专栏实战?

评论区留言告诉我你的需求,我会优先安排更新 ✅


⭐️ 若喜欢我,就请关注我叭~(更新不迷路)

⭐️ 若对你有用,就请点赞支持一下叭~(给我一点点动力)

⭐️ 若有疑问,就请评论留言告诉我叭~(我会补坑 & 更新迭代)


免责声明:本文仅用于学习与技术研究,请在合法合规、遵守站点规则与 Robots 协议的前提下使用相关技术。严禁将技术用于任何非法用途或侵害他人权益的行为。

相关推荐
一个无名的炼丹师2 小时前
DeepSeek+LangGraph构建企业级多模态RAG:从PDF复杂解析到Agentic智能检索全流程实战
python·pdf·大模型·多模态·rag
历程里程碑2 小时前
哈希3 : 最长连续序列
java·数据结构·c++·python·算法·leetcode·tornado
火云洞红孩儿2 小时前
2026年,用PyMe可视化编程重塑Python学习
开发语言·python·学习
2401_841495642 小时前
【LeetCode刷题】两两交换链表中的节点
数据结构·python·算法·leetcode·链表·指针·迭代法
幻云20102 小时前
Next.js 之道:从入门到精通
前端·javascript·vue.js·人工智能·python
SunnyDays10112 小时前
使用 Python 自动查找并高亮 Word 文档中的文本
经验分享·python·高亮word文字·查找word文档中的文字
深蓝电商API2 小时前
Selenium处理弹窗、警报和验证码识别
爬虫·python·selenium
深蓝电商API2 小时前
Selenium模拟滚动加载无限下拉页面
爬虫·python·selenium
小王子10242 小时前
Redis Queue 安装与使用
redis·python·任务队列·rq·redis queue