在 Bun 环境下实现一个网络爬虫是个不错的想法。Bun 提供了内置的 fetch API,使得发送 HTTP 请求变得非常简单。以下是一个基本的网络爬虫实现,它可以爬取指定网页的内容并提取所有链接:
- 首先,创建一个新的 Bun 项目:
mkdir bun-web-crawler
cd bun-web-crawler
bun init- 安装必要的依赖。我们将使用
cheerio来解析 HTML:
bun add cheerio- 创建一个名为
crawler.ts的文件,并添加以下代码:
import { load } from 'cheerio';
async function crawl(url: string, depth: number = 0, maxDepth: number = 2) {
if (depth > maxDepth) return;
console.log(`Crawling: ${url}`);
try {
const response = await fetch(url);
const html = await response.text();
const $ = load(html);
// 提取并打印页面标题
const title = $('title').text();
console.log(`Title: ${title}`);
// 提取所有链接
const links = $('a')
.map((i, el) => $(el).attr('href'))
.get()
.filter((href): href is string => typeof href === 'string')
.map(href => new URL(href, url).href)
.filter(href => href.startsWith('http'));
console.log(`Found ${links.length} links`);
// 递归爬取链接
for (const link of links) {
await crawl(link, depth + 1, maxDepth);
}
} catch (error) {
console.error(`Error crawling ${url}:`, error);
}
}
// 开始爬取
const startUrl = 'https://example.com';
crawl(startUrl);- 运行爬虫:
bun run crawler.ts这个简单的爬虫会执行以下操作:
- 发送 HTTP 请求获取指定 URL 的内容。
- 使用 Cheerio 解析 HTML 内容。
- 提取并打印页面标题。
- 提取页面中的所有链接。
- 递归爬取找到的链接,直到达到最大深度。
注意事项:
- 这个爬虫是一个基本实现,没有考虑很多实际情况,如重复 URL、速率限制等。
- 在实际使用中,你应该遵守网站的 robots. Txt 规则和爬虫礼仪。
- 对于大规模爬取,你可能需要添加并发控制、URL 队列管理、数据存储等功能。
增强功能:
- 添加延迟以避免过快请求:
function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 在每次请求前添加延迟
await delay(1000); // 1秒延迟- 使用 Set 来避免重复爬取:
const crawledUrls = new Set<string>();
async function crawl(url: string, depth: number = 0, maxDepth: number = 2) {
if (depth > maxDepth || crawledUrls.has(url)) return;
crawledUrls.add(url);
// ... 其余代码 ...
}- 添加错误处理和重试机制:
async function crawlWithRetry(url: string, depth: number, maxDepth: number, retries: number = 3