本文目录导读:

针对Python爬虫处理动态页面(JavaScript渲染),主要有以下三种主流方案,我按推荐度从高到低排列:
Playwright(推荐🔥)
现代、快速、官方维护,是Selenium的完美替代品。
from playwright.sync_api import sync_playwright
import time
with sync_playwright() as p:
# 启动浏览器(默认无头模式)
browser = p.chromium.launch(headless=False) # headless=True则不显示浏览器
page = browser.new_page()
# 设置合适的视口大小
page.set_viewport_size({"width": 1920, "height": 1080})
# 访问动态页面
page.goto("https://example.com/dynamic-page")
# 等待某个元素加载完成(推荐)
page.wait_for_selector(".content-loaded", timeout=10000)
# 或者等待网络空闲
page.wait_for_load_state("networkidle")
# 获取渲染后的HTML
html = page.content()
# 获取某个元素文本
text = page.text_content(".target-element")
# 截图调试
page.screenshot(path="debug.png")
browser.close()
安装:
pip install playwright playwright install chromium
Selenium(经典方案)
生态成熟,文档丰富,但速度较慢。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 配置
chrome_options = Options()
chrome_options.add_argument("--headless") # 无头模式
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
driver = webdriver.Chrome(options=chrome_options)
try:
driver.get("https://example.com/dynamic-page")
# 显式等待(推荐)
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "content-loaded"))
)
# 获取页面源码
html = driver.page_source
# 获取元素
text = driver.find_element(By.CLASS_NAME, "target-element").text
finally:
driver.quit()
Pyppeteer(异步方案)
基于Puppeteer的Python版本,异步处理性能好。
import asyncio
from pyppeteer import launch
async def main():
browser = await launch(headless=True)
page = await browser.newPage()
await page.goto("https://example.com/dynamic-page")
# 等待特定元素
await page.waitForSelector(".content-loaded")
# 获取内容
content = await page.content()
text = await page.querySelectorEval(".target-element", "el => el.textContent")
await browser.close()
asyncio.run(main())
进阶技巧
处理常见动态内容
# 处理无限滚动(Playwright示例)
async def scroll_to_bottom(page):
previous_height = await page.evaluate("document.body.scrollHeight")
while True:
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
await page.wait_for_timeout(2000) # 等待加载
new_height = await page.evaluate("document.body.scrollHeight")
if new_height == previous_height:
break
previous_height = new_height
# 点击加载更多按钮
page.click("button.load-more")
# 处理弹窗/登录
page.fill("input#username", "your_username")
page.fill("input#password", "your_password")
page.click("button[type='submit']")
# 拦截网络请求(性能优化)
page.route("**/*.{png,jpg,jpeg,gif}", lambda route: route.abort())
选择建议
| 方案 | 适用场景 | 速度 | 资源占用 | 学习曲线 |
|---|---|---|---|---|
| Playwright | 大多数情况 | 低 | ||
| Selenium | 传统项目/兼容性要求 | 中 | ||
| Pyppeteer | 异步/大规模爬取 | 中高 |
性能优化
# Playwright性能优化示例
with sync_playwright() as p:
browser = p.chromium.launch(
headless=True,
args=[
"--disable-gpu",
"--disable-dev-shm-usage",
"--no-sandbox",
"--disable-setuid-sandbox"
]
)
context = browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
viewport={"width": 1920, "height": 1080},
locale="zh-CN"
)
page = context.new_page()
# 设置超时
page.set_default_timeout(30000)
# 拦截不必要的资源
page.route("**/*.{png,jpg,jpeg,gif,svg,ico}", lambda route: route.abort())
page.route("**/*.{woff,woff2,ttf,eot}", lambda route: route.abort())
如果你是新手或需要快速上手,推荐使用 Playwright;如果是已有Selenium项目就继续用Selenium;需要高性能异步爬取选Pyppeteer。