当然可以,下面是一个更完整的 TypeScript 爬虫实例,它不仅使用 TypeScript,还展示了一些常见的爬虫技巧,比如递归抓取和存储抓取结果。
步骤一:设置项目
-
创建一个新的项目目录并初始化 Bun 项目:
mkdir my-web-crawler cd my-web-crawler bun init -
安装 TypeScript 和相关类型定义:
bun add -d typescript @types/node -
初始化 TypeScript 配置文件:
npx tsc --init
步骤二:安装所需依赖
安装用于 HTTP 请求和 HTML 解析的库:
bun add axios cheerio步骤三:编写爬虫代码
创建一个 src 目录并在其中创建一个 crawler.ts 文件:
// src/crawler.ts
import axios from 'axios';
import cheerio from 'cheerio';
import * as fs from 'fs';
const startUrl = 'https://example.com'; // 你要抓取的起始网站URL
const visitedUrls = new Set<string>();
const maxDepth = 2;
async function fetchHTML(url: string): Promise<string> {
const { data } = await axios.get(url);
return data;
}
async function parseHTML(url: string, html: string, depth: number): Promise<void> {
const $ = cheerio.load(html);
const links: string[] = [];
$('a').each((index, element) => {
const link = $(element).attr('href');
if (link && isValidUrl(link)) {
links.push(new URL(link, url).href);
}
});
saveLinksToFile(url, links);
if (depth < maxDepth) {
for (const link of links) {
if (!visitedUrls.has(link)) {
visitedUrls.add(link);
await crawl(link, depth + 1);
}
}
}
}
function isValidUrl(link: string): boolean {
return link.startsWith('http');
}
function saveLinksToFile(url: string, links: string[]): void {
const fileName = 'crawled_links.txt';
const data = `URL: ${url}\nLinks:\n${links.join('\n')}\n\n`;
fs.appendFileSync(fileName, data);
}
async function crawl(url: string, depth: number): Promise<void> {
try {
const html = await fetchHTML(url);
await parseHTML(url, html, depth);
} catch (error) {
console.error(`Error occurred while crawling ${url}:`, error);
}
}
async function main() {
visitedUrls.add(startUrl);
await crawl(startUrl, 0);
}
main();步骤四:配置 TypeScript
编辑 tsconfig.json,确保编译目标和模块解析适用于 Bun 环境:
{
"compilerOptions": {
"target": "es2020",
"module": "esnext",
"moduleResolution": "node",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src"]
}步骤五:编译并运行爬虫
编译 TypeScript 代码:
bun tsc运行编译后的 JavaScript 代码:
bun run dist/crawler.js代码解释
fetchHTML函数: 使用axios库发送 HTTP GET 请求并返回 HTML 字符串。parseHTML函数: 使用cheerio库解析 HTML 并提取所有链接,递归抓取到指定深度。isValidUrl函数: 检查链接是否是有效的 URL。saveLinksToFile函数: 将抓取的链接保存到一个文件中。crawl函数: 控制抓取过程,防止重复抓取已访问的 URL。main函数: 初始化抓取过程。
通过这个示例,你可以了解如何在 Bun 环境下使用 TypeScript 编写一个递归爬虫,并保存抓取结果到文件。你可以根据需要进一步扩展这个爬虫,比如添加更多的抓取策略、处理不同的 HTML 结构等。