零基础精通Crawlee:Node.js网页抓取实战指南
你是否曾因网页抓取遇到重重困难?静态网页爬取简单但无法处理动态内容,复杂爬虫又需要处理代理、会话管理等繁琐工作。现在,Crawlee来了!作为专为Node.js设计的网页抓取和浏览器自动化库,它能帮助你快速构建可靠、高效的爬虫项目,轻松应对各种网页抓取挑战。
环境配置避坑指南
系统要求与版本检查
在开始使用Crawlee之前,确保你的开发环境满足以下要求:
node -v # 需Node.js 16.x或更高版本
npm -v # 建议npm 7.x以上
如果版本不满足要求,请到Node.js官网下载并安装最新LTS版本。
三种安装方式对比
| 安装方式 | 适用场景 | 命令 | 优势 |
|---|---|---|---|
| CLI工具 | 全新项目 | npx crawlee create my-crawler |
自动生成完整项目结构 |
| 基础安装 | 静态网页爬取 | npm install crawlee |
轻量级,仅包含基础功能 |
| 完整安装 | 动态网页爬取 | npm install crawlee playwright |
支持浏览器渲染,功能全面 |
推荐使用CLI工具创建新项目,它会自动配置好目录结构和依赖项:
npx crawlee create my-crawler
cd my-crawler
npm start # 运行示例爬虫
运行成功后,你将看到示例爬虫已经开始工作,爬取结果会保存在项目的storage目录中。
核心功能解析:解决不同网页抓取难题
静态网页抓取:快速高效的数据提取 ⚡
对于服务器端渲染的静态网页,CheerioCrawler是最佳选择。它基于Cheerio解析HTML,速度快且资源占用低:
import { CheerioCrawler } from 'crawlee';
// 创建爬虫实例
const crawler = new CheerioCrawler({
// 每个请求的处理函数
async requestHandler({ $, request }) {
// 使用类似jQuery的语法提取数据
const title = $('title').text();
const headings = [];
$('h1, h2, h3').each((i, el) => {
headings.push($(el).text());
});
console.log(`成功抓取: ${title}`);
// 保存数据
await Dataset.pushData({
url: request.url,
title,
headings,
timestamp: new Date().toISOString()
});
}
});
// 启动爬虫
await crawler.run(['https://example.com']);
动态网页抓取:处理JavaScript渲染内容 🚀
现代网站大量使用JavaScript动态加载内容,这时需要使用PlaywrightCrawler或PuppeteerCrawler:
import { PlaywrightCrawler } from 'crawlee';
const crawler = new PlaywrightCrawler({
// 显示浏览器窗口,方便调试
headless: false,
async requestHandler({ page, request }) {
// 等待页面加载完成
await page.waitForLoadState('networkidle');
// 提取动态生成的内容
const productTitles = await page.$$eval('.product-title', elements =>
elements.map(el => el.textContent.trim())
);
console.log(`在${request.url}找到${productTitles.length}个产品`);
// 保存数据
await Dataset.pushData({
url: request.url,
products: productTitles,
count: productTitles.length
});
}
});
await crawler.run(['https://example.com/products']);
智能链接发现:整站爬取自动化
Crawlee的enqueueLinks功能可以自动发现并添加新的URL,实现整站爬取:
// 在requestHandler中添加
await enqueueLinks({
// 只抓取特定选择器的链接
selector: 'a.product-link',
// 过滤URL,只保留同一域名下的链接
filter: ({ url }) => url.hostname === 'example.com',
// 为新请求添加额外元数据
requestTemplate: {
userData: {
label: 'product'
}
}
});
渐进式实战案例:从单页抓取到整站爬虫
基础:单页数据提取
让我们从一个简单的单页抓取开始,提取网页标题和元描述:
import { CheerioCrawler, Dataset } from 'crawlee';
// 创建爬虫
const crawler = new CheerioCrawler({
async requestHandler({ $, request }) {
// 提取数据
const data = {
url: request.url,
title: $('title').text(),
metaDescription: $('meta[name="description"]').attr('content') || '无描述',
timestamp: new Date().toISOString()
};
// 输出结果
console.log(`抓取: ${data.title}`);
// 保存到数据集
await Dataset.pushData(data);
}
});
// 启动爬虫
await crawler.run(['https://crawlee.dev']);
运行后,查看storage/datasets/default目录下的JSON文件,你将看到抓取到的数据。
进阶:整站内容爬取
接下来,我们构建一个能够爬取整个网站的爬虫,自动发现并访问新页面:
import { PlaywrightCrawler, Dataset } from 'crawlee';
// 定义要排除的URL模式
const EXCLUDE_PATTERNS = [/logout/, /admin/, /cart/];
const crawler = new PlaywrightCrawler({
// 浏览器配置
headless: true,
// 并发控制
maxConcurrency: 2,
// 请求处理函数
async requestHandler({ page, enqueueLinks, request }) {
console.log(`正在处理: ${request.url}`);
// 提取页面信息
const title = await page.title();
const h1 = await page.$eval('h1', el => el?.textContent || '无H1标题');
// 保存数据
await Dataset.pushData({
url: request.url,
title,
h1,
depth: request.userData.depth || 0,
timestamp: new Date().toISOString()
});
// 发现并添加新链接
await enqueueLinks({
selector: 'a',
filter: ({ url }) => {
// 排除不需要的链接
return !EXCLUDE_PATTERNS.some(pattern => pattern.test(url.href));
},
requestTemplate: {
userData: {
depth: (request.userData.depth || 0) + 1
}
},
// 限制爬取深度
maxDepth: 3
});
}
});
// 启动爬虫,从首页开始
await crawler.run(['https://example.com']);
运行后,爬虫将从起始URL开始,自动发现并爬取最多3层深度的链接,所有数据会保存在数据集中。
高级:反屏蔽策略配置
许多网站会阻止频繁的爬虫请求,Crawlee内置了强大的反屏蔽机制:
import { PlaywrightCrawler } from 'crawlee';
const crawler = new PlaywrightCrawler({
// 启用会话池管理
useSessionPool: true,
sessionPoolOptions: {
// 每个会话最多使用5次
sessionOptions: { maxUsageCount: 5 },
// 会话过期时间
sessionExpirySecs: 300
},
// 配置代理(如果有)
proxyConfiguration: {
proxyUrls: [
'http://proxy1:port',
'http://proxy2:port'
]
},
// 请求延迟
minConcurrency: 1,
maxConcurrency: 3,
// 随机延迟
requestHandlerTimeoutSecs: 30,
// 重试失败请求
maxRequestRetries: 3,
// 指数退避重试
retryPolicy: {
backoffStrategy: 'exponential',
initialDelaySecs: 1
},
async requestHandler({ page, request }) {
// 页面处理逻辑
console.log(`使用会话${request.sessionId}访问: ${request.url}`);
// ...
}
});
await crawler.run(['https://target-website.com']);
常见问题解决方案(Q&A)
Q: 爬虫运行时提示"内存不足"怎么办?
A: 可以通过以下方式解决:
- 降低并发数:
maxConcurrency: 2 - 启用自动扩展:
autoscaledPoolOptions: { maxConcurrency: 5 } - 增加内存限制:
node --max-old-space-size=4096 src/main.js
Q: 如何处理需要登录的网站?
A: 使用页面交互功能实现登录:
async requestHandler({ page }) {
// 检查是否需要登录
if (await page.$('#login-form')) {
// 输入用户名密码
await page.fill('#username', 'your-username');
await page.fill('#password', 'your-password');
// 提交表单
await page.click('#submit-button');
// 等待登录完成
await page.waitForNavigation();
}
// 登录后的处理...
}
Q: 如何存储和导出抓取的数据?
A: Crawlee提供多种数据存储方式:
// 导出为CSV
await Dataset.exportToCSV('results');
// 导出为JSON
await Dataset.exportToJSON('results');
// 直接访问数据记录
const dataset = await Dataset.open();
for await (const item of dataset) {
console.log(item);
}
扩展资源导航
官方文档与示例
- 快速入门指南:[docs/quick-start/index.mdx]
- 完整API参考:[packages/core/src/index.ts]
- 示例代码库:[docs/examples/]
进阶学习路径
- 基础:掌握三种核心爬虫类型的使用
- 中级:实现反屏蔽策略和会话管理
- 高级:分布式爬取和云平台部署
- 专家:自定义爬虫逻辑和插件开发
社区资源
- GitHub仓库:通过
git clone https://gitcode.com/GitHub_Trending/cr/crawlee获取完整源码 - 问题讨论:项目GitHub Issues页面
- 教程合集:[docs/guides/]目录下的各类专题指南
Crawlee作为Node.js生态中强大的网页抓取工具,不仅简化了爬虫开发流程,还提供了企业级的稳定性和性能优化。无论你是需要快速获取少量数据,还是构建大规模的网页抓取系统,Crawlee都能满足你的需求。现在就动手创建你的第一个Crawlee项目,开启高效网页抓取之旅吧!
GLM-5智谱 AI 正式发布 GLM-5,旨在应对复杂系统工程和长时域智能体任务。Jinja00
GLM-5-w4a8GLM-5-w4a8基于混合专家架构,专为复杂系统工程与长周期智能体任务设计。支持单/多节点部署,适配Atlas 800T A3,采用w4a8量化技术,结合vLLM推理优化,高效平衡性能与精度,助力智能应用开发Jinja00
jiuwenclawJiuwenClaw 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。Python0193- QQwen3.5-397B-A17BQwen3.5 实现了重大飞跃,整合了多模态学习、架构效率、强化学习规模以及全球可访问性等方面的突破性进展,旨在为开发者和企业赋予前所未有的能力与效率。Jinja00
AtomGit城市坐标计划AtomGit 城市坐标计划开启!让开源有坐标,让城市有星火。致力于与城市合伙人共同构建并长期运营一个健康、活跃的本地开发者生态。01
awesome-zig一个关于 Zig 优秀库及资源的协作列表。Makefile00

