项目概述
本项目旨在模仿Crawl4AI,开发一个基于.NET8的简单AI爬虫工具,支持JavaScript渲染,封装为Docker镜像,通过API提供服务,并部署在Ubuntu 24上。以下是详细的架构设计和实施指南。
技术栈
组件 | 技术 | 用途 |
---|---|---|
后端框架 | ASP.NET Core Web API (.NET8) | 提供RESTful API,处理爬虫请求 |
浏览器自动化 | Playwright for .NET | 控制无头Chrome,渲染JavaScript |
HTML解析 | HtmlAgilityPack 或 AngleSharp | 解析HTML,使用CSS/XPath提取数据 |
容器化 | Docker | 打包应用,确保部署一致性 |
架构设计
1. 应用结构
- ASP.NET Core Web API:核心服务,暴露端点如
POST /api/crawl
,接受URL和提取参数(如CSS选择器),返回提取的数据。 - Playwright for .NET:用于启动无头Chrome浏览器,加载网页并渲染动态内容。
- HtmlAgilityPack/AngleSharp:解析渲染后的HTML,基于用户提供的CSS或XPath选择器提取数据。
- 数据格式:输出JSON或Markdown格式,适合AI应用(如RAG或LLM数据管道)。
2. API端点示例
端点 | 方法 | 请求体 | 响应 |
---|---|---|---|
/api/crawl | POST | { "url": "https://example.com", "extraction": { "type": "css", "selector": "h1" } } | { "data": "Example Domain" } |
3. 工作流程
- 用户通过API发送爬取请求,指定目标URL和提取规则。
- Web API调用Playwright,启动无头Chrome,加载网页并等待动态内容渲染。
- 使用HtmlAgilityPack或AngleSharp解析页面HTML,应用CSS/XPath提取数据。
- 将提取的数据格式化为JSON或Markdown,返回给用户。
- 错误处理:处理无效URL、超时或提取失败等情况,返回适当的错误信息。
实施步骤
1. 项目设置
-
创建一个新的ASP.NET Core Web API项目:
dotnet new webapi -n WebCrawler
-
添加必要的NuGet包:
Microsoft.Playwright
HtmlAgilityPack
或AngleSharp
2. 集成Playwright
-
初始化Playwright并配置无头Chrome:
using var playwright = await Playwright.CreateAsync(); await using var browser = await playwright.Chromium.LaunchAsync(new() { Headless = true }); var page = await browser.NewPageAsync(); await page.GotoAsync("https://example.com");
-
确保等待动态内容加载(如使用
page.WaitForSelectorAsync
)。
3. 数据提取
-
使用HtmlAgilityPack解析HTML:
var doc = new HtmlDocument(); doc.LoadHtml(await page.ContentAsync()); var nodes = doc.DocumentNode.SelectNodes("//h1");
-
或使用AngleSharp:
var config = Configuration.Default; var context = BrowsingContext.New(config); var document = await context.OpenAsync(req => req.Content(await page.ContentAsync())); var elements = document.QuerySelectorAll("h1");
4. API控制器
-
创建控制器处理爬取请求:
[ApiController] [Route("api/[controller]")] public class CrawlController : ControllerBase { [HttpPost] public async Task<IActionResult> Crawl([FromBody] CrawlRequest request) { // Playwright爬取和提取逻辑 return Ok(new { Data = "提取的数据" }); } }
5. Docker打包
-
创建以下Dockerfile,使用多阶段构建:
# 构建阶段 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["WebCrawler.csproj", "."] RUN dotnet restore COPY . . RUN dotnet publish -c Release -o /app # 运行时阶段 FROM mcr.microsoft.com/playwright/dotnet:v1.51.1-jammy WORKDIR /app COPY --from=build /app . ENTRYPOINT ["dotnet", "WebCrawler.dll"]
-
构建和运行:
docker build -t webcrawler . docker run -p 8080:80 webcrawler
6. 部署到Ubuntu 24
-
安装Docker:
sudo apt update sudo apt install docker.io sudo systemctl start docker sudo systemctl enable docker
-
运行容器:
docker run -d -p 8080:80 webcrawler
-
访问API:
http://localhost:8080/api/crawl
优化Docker镜像大小
- 多阶段构建:仅将发布后的应用文件复制到运行时镜像,减少构建工件。
- 官方镜像:
microsoft/playwright-dotnet
包含预装的浏览器和.NET运行时,避免手动安装。 - 清理缓存:在构建过程中使用
--no-cache
或清理临时文件。 - 局限性:浏览器二进制文件(如Chrome)不可避免地增加镜像大小,可能达到数百MB,但这是支持JavaScript渲染的必要代价。
注意事项
- Playwright依赖:确保Docker镜像包含所有浏览器运行所需的系统依赖(如字体和库),
microsoft/playwright-dotnet
已预配置这些依赖。 - 错误处理:实现健壮的错误处理机制,处理网络错误、超时或无效选择器。
- 扩展性:当前设计为单URL爬取,如需支持多URL或深度爬取,可添加队列机制或链接跟随逻辑。
- AI友好性:输出的JSON或Markdown格式适合AI数据管道,可根据需要扩展支持LLM提取(需额外集成AI服务)。
示例API请求
POST /api/crawl
Content-Type: application/json
{
"url": "https://example.com",
"extraction": {
"type": "css",
"selector": "h1"
}
}
响应:
{
"data": "Example Domain"
}