HOOOS

使用Playwright抓取动态网页内容的实战技巧,以需要登录的页面为例

0 15 代码捕手 Playwright爬虫动态网页抓取自动化测试
Apple

传统爬虫遇到动态加载内容就束手无策——页面数据通过AJAX异步加载、需要执行JavaScript才能渲染、登录状态校验严格。Playwright作为现代浏览器自动化工具,能完美模拟人类操作:

  • 支持Chromium/Firefox/WebKit三大内核
  • 自动等待元素加载完成
  • 可处理Cookie和本地存储
  • 执行复杂交互动作

环境准备(Node.js示例)

npm init -y
npm install playwright

建议使用async/await语法,处理异步操作更直观。初始化浏览器实例时,建议关闭headless模式调试:

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ 
    headless: false, // 调试时设为可见
    slowMo: 500 // 操作延迟毫秒数
  });
})();

突破登录验证的4个关键步骤

1. 模拟登录流程

以知乎为例,需要处理手机号+密码登录:

const page = await browser.newPage();
await page.goto('https://www.zhihu.com/signin');

// 切换至密码登录标签
await page.click('div.SignContainer-switch span');

// 填写表单
await page.fill('input[name="username"]', 'your_phone');
await page.fill('input[name="password"]', 'your_password');

// 触发验证码(如有)
await page.click('button.SignFlow-submitButton');

// 人工介入处理验证码
await page.waitForTimeout(30000); // 留30秒手动操作

2. 保存登录状态

避免每次重复登录,可持久化存储cookies:

// 登录成功后获取cookies
const cookies = await page.context().cookies();
const fs = require('fs');
fs.writeFileSync('cookies.json', JSON.stringify(cookies));

// 下次启动时恢复会话
const loadedCookies = JSON.parse(fs.readFileSync('cookies.json'));
await page.context().addCookies(loadedCookies);

3. 处理动态加载内容

典型场景:滚动加载的微博feed流

// 连续滚动5次
for (let i = 0; i < 5; i++) {
  await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
  await page.waitForSelector('div.new-loading', { state: 'hidden' });
}

// 获取所有动态内容
const posts = await page.$$eval('div.WB_feed_detail', nodes => 
  nodes.map(n => ({
    content: n.querySelector('div.WB_text').innerText,
    time: n.querySelector('div.WB_from').innerText
  }))
);

4. 绕过反爬机制

  • 随机延迟:在关键操作间添加page.waitForTimeout(Math.random() * 3000 + 1000)
  • 修改指纹:启动时传入userAgent参数
  • 代理IP:通过proxy配置项实现
  • 规避检测:禁用WebDriver特征
const browser = await chromium.launch({
  args: [
    '--disable-blink-features=AutomationControlled'
  ],
  proxy: { 
    server: 'http://proxy.example.com:8080'
  }
});

实战案例:抓取淘宝商品评论

  1. 登录后跳转目标商品页
  2. 自动点击"累计评论"标签
  3. 循环点击"下一页"直到末页
  4. 使用page.$$eval提取评论数据
  5. 异常处理:网络超时/元素消失/验证码触发
try {
  await page.click('div.tab-panel li[data-value="feed"]', { timeout: 5000 });
} catch (err) {
  console.log('可能遇到验证码,需要人工干预');
  await page.screenshot({ path: 'error.png' });
}

性能优化建议

  • 并行处理:创建多个browserContext实现并发
  • 资源控制:page.route拦截不必要的图片/样式表请求
  • 内存管理:定期关闭闲置page实例
  • 错误重试:实现指数退避重试机制
// 拦截图片请求
await page.route('**/*.{png,jpg,jpeg}', route => route.abort());

遇到验证码怎么办?推荐两种方案:

  1. 商业打码平台(超验/联众等)
  2. 人工介入时使用page.pause()进入调试模式

记住:遵守robots.txt协议,控制请求频率,避免对目标网站造成负担。

点评评价

captcha
健康