闲社
标题:
【教程】Puppeteer自动化抓取实战:零代码基础也能写的网页数据采集脚本
[打印本页]
作者:
kai_va
时间:
3 小时前
标题:
【教程】Puppeteer自动化抓取实战:零代码基础也能写的网页数据采集脚本
【前言】
最近 GitHub Trending 上 Puppeteer 又火了,94K+ Star 的 Chrome/Firefox 自动化神器。很多兄弟想写爬虫但怕被封、怕写代码复杂,今天这篇手把手教你用 Puppeteer 写一个
零依赖、防检测、带重试
的网页数据采集脚本,全程 Node.js,复制粘贴就能跑。
【前置条件】
Node.js 18+(推荐用 nvm 安装最新 LTS)
一个终端(Windows 用 PowerShell,Mac/Linux 用自带 Terminal)
目标网站:不需要登录的公开页面(本文以采集新闻列表为例)
【步骤一:安装 Puppeteer】
打开终端,一行命令搞定:
npm install puppeteer
复制代码
Puppeteer 会自动下载匹配的 Chromium 浏览器,不需要你手动安装 Chrome。如果下载慢,换国内镜像:
npm config set puppeteer_download_host=https://npmmirror.com/mirrors
npm install puppeteer
复制代码
【步骤二:写第一个采集脚本】
新建文件
scraper.js
复制代码
,内容如下:
const puppeteer = require('puppeteer');
(async () => {
// 1. 启动浏览器(headless: true 表示无界面,后台跑)
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
// 2. 设置 User-Agent,模拟真实浏览器
await page.setUserAgent(
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36'
);
// 3. 设置视口,避免被识别为无头浏览器
await page.setViewport({ width: 1920, height: 1080 });
// 4. 打开目标页面
await page.goto('https://news.example.com/list', {
waitUntil: 'networkidle2', // 等网络空闲再开始
timeout: 30000
});
// 5. 提取数据(用 page.evaluate 在页面上下文中执行 JS)
const articles = await page.evaluate(() => {
const items = document.querySelectorAll('.news-item');
return Array.from(items).map(item => ({
title: item.querySelector('h2')?.innerText?.trim(),
link: item.querySelector('a')?.href,
summary: item.querySelector('.summary')?.innerText?.trim(),
date: item.querySelector('.date')?.innerText?.trim()
}));
});
console.log('采集到', articles.length, '条数据');
console.log(JSON.stringify(articles, null, 2));
// 6. 关闭浏览器
await browser.close();
})();
复制代码
运行:
node scraper.js
复制代码
【步骤三:增强版——防检测 + 自动重试】
很多网站会检测无头浏览器,升级脚本加入反检测:
const puppeteer = require('puppeteer');
async function scrapeWithRetry(url, maxRetries = 3) {
for (let attempt = 1; attempt {
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3] });
});
await page.setUserAgent(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36'
);
await page.setViewport({ width: 1920, height: 1080 });
// 设置更真实的请求头
await page.setExtraHTTPHeaders({
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
});
await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });
// 等 2-5 秒随机延迟,模拟人类阅读
await page.waitForTimeout(2000 + Math.random() * 3000);
const data = await page.evaluate(() => {
const items = document.querySelectorAll('.news-item');
return Array.from(items).map(item => ({
title: item.querySelector('h2')?.innerText?.trim(),
link: item.querySelector('a')?.href,
summary: item.querySelector('.summary')?.innerText?.trim()
})).filter(i => i.title);
});
await browser.close();
return data;
} catch (err) {
console.log(`第 ${attempt} 次尝试失败: ${err.message}`);
await browser.close();
if (attempt === maxRetries) throw err;
await new Promise(r => setTimeout(r, 5000 * attempt)); // 递增延迟
}
}
}
(async () => {
const result = await scrapeWithRetry('https://news.example.com/list');
console.log('最终采集结果:', JSON.stringify(result, null, 2));
})();
复制代码
【步骤四:保存到文件 / 数据库】
采集完的数据存到 JSON 文件:
const fs = require('fs');
// 在 scrapeWithRetry 返回后添加:
fs.writeFileSync('data.json', JSON.stringify(result, null, 2));
console.log('已保存到 data.json');
复制代码
如果要存到数据库,用 SQLite 最简单:
npm install better-sqlite3
复制代码
const Database = require('better-sqlite3');
const db = new Database('articles.db');
db.exec(`
CREATE TABLE IF NOT EXISTS articles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
link TEXT,
summary TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
const insert = db.prepare('INSERT INTO articles (title, link, summary) VALUES (?, ?, ?)');
result.forEach(item => insert.run(item.title, item.link, item.summary));
console.log('已存入数据库');
复制代码
【常见问题】
Q: 页面加载空白?
A: 可能是 SPA(单页应用),需要等 JS 渲染完。加
await page.waitForSelector('.news-item')
复制代码
再提取数据。
Q: 被网站封 IP 了?
A: 降低请求频率,加随机延迟(3-10秒),或用代理:
args: ['--proxy-server=http://ip:port']
复制代码
Q: 中文乱码?
A: 确保终端编码是 UTF-8,Windows 执行
chcp 65001
复制代码
Q: 某些元素选不到?
A: 用浏览器 DevTools 右键元素 → Copy → Copy selector,粘贴到
document.querySelector('这里')
复制代码
【总结】
本文从安装到实战,完整走了一遍 Puppeteer 网页采集流程:
Puppeteer 安装 + 基础采集脚本
反检测技巧(覆盖 webdriver、设置真实 UA、随机延迟)
自动重试机制,提高稳定性
数据保存到 JSON 和 SQLite
这套代码可以直接拿去改 selector 就能采集任何公开网页。GitHub 上 Puppeteer 94K+ Star 不是白给的,自动化测试、数据采集、截图生成都能用。有问题楼下交流,代码有 bug 直接贴错误日志。
参考:GitHub Trending 今日热门项目 puppeteer/puppeteer
欢迎光临 闲社 (https://www.xianshe.com/)
Powered by Discuz! X5.0