由需求反思爬虫设计:所见即所提取
Table of Contents
场景
需要提取一个业务数据表格。
传统思路的困境:
- 数据分散在多个数据库
- 前端有数据处理逻辑
- 多个后端服务都会修改数据
- 要理清数据流转简直噩梦
换个思路: 用户在页面上看到的就是最终结果,直接提取不就行了?
所见即所提取
与其追着数据源头跑,不如直接拿最终渲染结果。
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com/data-page');
// 直接提取表格内容
const rows = await page.locator('table tbody tr').all();
const data = await Promise.all(rows.map(async row => {
const cells = await row.locator('td').allTextContents();
return cells;
}));
await browser.close();
console.log(data); // 拿到了
优势:
- 快速:几分钟搞定
- 稳定:页面结构变化比数据流逻辑变化慢得多
- 简单:不需要理解业务,不需要申请数据库权限
Playwright 常用速记
启动(带状态保持)
// 推荐:launchPersistentContext 保留登录状态和 cookies
const context = await chromium.launchPersistentContext(
'/tmp/playwright-profile', // 用户数据目录
{
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
headless: false, // 显示浏览器窗口
slowMo: 500, // 操作减速,方便观察
channel: 'chrome', // 使用 Chrome 而非 Chromium
}
);
const page = context.pages()[0] || await context.newPage();
基础操作
// 导航
await page.goto(url, { waitUntil: 'networkidle' });
// 交互
await page.locator('selector').click();
await page.locator('input').fill('text');
await page.locator('select').selectOption('value');
// 提取
const text = await page.locator('.class').textContent();
const items = await page.locator('.item').allTextContents();
const html = await page.locator('.container').innerHTML();
const attr = await page.locator('a').getAttribute('href');
// 等待
await page.waitForSelector('.class', { state: 'visible' });
await page.waitForLoadState('networkidle');
await page.waitForTimeout(1000); // 固定延迟(不推荐但有时必要)
// 截图调试
await page.screenshot({ path: 'debug.png', fullPage: true });
实用选项
// 设置视口
await page.setViewportSize({ width: 1920, height: 1080 });
// 拦截请求(屏蔽图片等)
await page.route('**/*.{png,jpg,jpeg}', route => route.abort());
// 执行自定义脚本
await page.addInitScript(() => {
Object.defineProperty(navigator, 'webdriver', { get: () => false });
});
总结
产品对着 CRM 告知需要哪些数据。并没有快速聚合的方式,且数据落在不同的数据库,很难聚合。
对后端来说,快速提取业务数据,通过爬虫的方式从数据源直接提取。不需要根据数据源反推数据库中的形式。实现比找前后端代码和数据库快多了。
用户看到什么,就提取什么。简单,直接。