tio-boot整合playwright 将网页内容转为markdown
tio-boot官网
playwright
简介
1. 什么是 Playwright
Playwright 是一个用于自动化网页测试和浏览器操作的现代工具,由微软开发。它支持多种浏览器,包括 Chromium、Firefox 和 WebKit,并提供跨浏览器一致的 API。以下是 Playwright 的一些关键特点:
- 多浏览器支持:Playwright 支持 Chromium(包括 Google Chrome 和 Microsoft Edge)、Firefox 和 WebKit(包括 Safari)。这使得开发者可以在多个浏览器上进行一致的测试。
- 自动化测试:Playwright 提供强大的自动化测试功能,支持测试用例的编写和执行,可以用于端到端(E2E)测试,功能测试和回归测试等。
- 丰富的 API:Playwright 拥有一个强大而直观的 API,用于浏览器自动化、页面导航、表单填写、截图、PDF 生成等。
- 并行测试:Playwright 支持并行执行测试,这使得测试可以更快完成,从而提高 CI/CD 管道的效率。
- 无头模式和有头模式:Playwright 支持无头模式(headless)和有头模式(headful),无头模式下不会打开浏览器窗口,有头模式下则会。
- 跨平台:Playwright 可以在 Windows、Mac 和 Linux 上运行,并且可以在本地和 CI 环境中使用。
- 自动处理页面同步:Playwright 自动处理页面加载、元素可见性和其他同步问题,减少了开发者手动等待的需求。
- 强大的选择器:Playwright 提供多种选择器策略,包括 CSS 选择器、文本选择器、XPath 等,方便定位页面元素。
- 网络拦截和模拟:Playwright 允许拦截和模拟网络请求,可以用于测试不同的网络条件和 API 响应。
- 截图和视频录制:Playwright 支持截取网页截图和录制测试过程的视频,有助于调试和记录测试结果。
总的来说,Playwright 是一个功能强大且灵活的网页自动化工具,适用于各种测试和自动化需求。
2. Playwright 和 Selenium 的关系
Playwright 和 Selenium 都是用于浏览器自动化的工具,但它们有一些关键的区别和特点:
历史背景:
- Selenium:Selenium 是一个开源的自动化工具,早于 Playwright 出现,已经有很多年历史。它支持多种浏览器(Chrome、Firefox、Safari、Edge 等)和编程语言(如 Java、Python、C#、Ruby 等)。Selenium 的设计理念是在多个浏览器中提供一致的自动化 API。
- Playwright:Playwright 是由微软开发的相对较新的自动化框架。它专注于现代 Web 应用的测试,支持 Chromium、Firefox 和 WebKit。Playwright 的设计目标是提供更高效、稳定和一致的自动化体验。
API 和功能:
- Selenium:Selenium 提供了一个广泛的 API,但在处理一些现代 Web 应用中的复杂交互时,可能会遇到一些问题。它的 API 在不同浏览器间的一致性方面有时会出现差异。
- Playwright:Playwright 提供了更现代化的 API,支持自动处理页面同步、网络拦截、模拟等功能。它的 API 一致性较好,可以在多个浏览器中实现相似的行为。
性能和稳定性:
- Selenium:由于 Selenium 的历史悠久,它在性能和稳定性方面可能会遇到一些挑战,特别是在复杂的 Web 应用场景中。
- Playwright:Playwright 在性能和稳定性方面有优势,尤其是在处理现代 Web 应用和复杂用户交互时。它的并行测试和自动同步功能可以显著提高测试效率。
3. Playwright 是否是客户端服务器模式?
Playwright 本身不是客户端-服务器模式的工具,而是一个客户端库。它通过客户端库与浏览器进行交互,这些浏览器实例可以运行在本地机器或远程服务器上。以下是 Playwright 的架构和工作方式:
- 客户端库:Playwright 提供了一个客户端库,开发者通过这个库编写测试脚本和自动化任务。这个库可以与 Chromium、Firefox 和 WebKit 浏览器进行通信。
- 浏览器实例:浏览器实例可以在本地机器上运行,也可以在远程服务器上运行(通过远程浏览器调试协议)。Playwright 支持这种灵活的配置,但它自身并不提供服务器功能。
- Playwright Server:在某些情况下,Playwright 可以与一个独立的 Playwright Server 进行交互,这个服务器负责提供浏览器实例并处理自动化请求。但这种模式更多的是用于集成测试环境,而不是 Playwright 的主要设计模式。
总结来说,Playwright 主要是一个客户端库,用于与浏览器进行自动化交互,不是传统意义上的客户端-服务器模式工具。
4. Playwright 对 java 的支持
Playwright 支持 Java。Playwright 提供了官方的 Java 客户端库,允许开发者使用 Java 编写测试脚本和进行浏览器自动化操作。Playwright 的 Java 客户端库与其他语言的客户端库一样,提供了丰富的功能,用于处理浏览器交互、页面操作和自动化测试等任务。
如何使用 Playwright 的 Java 客户端库
安装 Playwright Java 客户端库:
使用 Maven 或 Gradle 来添加 Playwright 的依赖。Maven 配置示例:
<dependency> <groupId>com.microsoft.playwright</groupId> <artifactId>playwright</artifactId> <version>1.27.0</version> <!-- 请检查最新版本 --> </dependency>
playwright 的客户端 driver-bundle-1.27.0.jar 有 117M
Gradle 配置示例:
dependencies { implementation 'com.microsoft.playwright:playwright:1.27.0' // 请检查最新版本 }
- 编写 Playwright 测试脚本:
使用 Java 编写测试脚本的基本示例如下:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.BrowserType.LaunchOptions;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Page.ScreenshotOptions;
import com.microsoft.playwright.Playwright;
public class PlaywrightExample {
public static void main(String[] args) {
String url = "https://www.sjsu.edu/classes/calendar/2024-2025.php";
// 创建 Playwright 实例
try (Playwright playwright = Playwright.create()) {
// 启动 Chromium 浏览器
LaunchOptions launchOptions = new BrowserType.LaunchOptions().setHeadless(true);
Browser browser = playwright.chromium().launch(launchOptions);
// 创建新页面
BrowserContext context = browser.newContext();
Page page = context.newPage();
// 导航到网页
page.navigate(url);
// 截取页面截图
ScreenshotOptions screenshotOptions = new Page.ScreenshotOptions().setPath(Paths.get("example.png"));
page.screenshot(screenshotOptions);
//获取内容,写入数据
String content = page.content();
try {
Files.write(Paths.get("remote_page.html"), content.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
// 关闭浏览器
browser.close();
}
}
}
第一次启动会自动下载
- FFMPEG playwright build v1007 1.4 Mb
- Firefox 105.0.1 (playwright build v1357) 77 Mb
- Webkit 16.0 (playwright build v1724) 58Mb
- Chromium 107.0.5304.18 (playwright build v1028).109.2 Mb
- 运行测试:
确保您的项目配置正确,并且 Playwright 的相关依赖已经被下载。运行您的 Java 应用程序以执行 Playwright 脚本。
远程连接
Playwright 支持服务器模式,启动 Playwright 服务器后可以使用 Java 进行远程浏览器连接。
我们可以将 Playwright 配置为与远程浏览器进行交互,这对于在分布式测试环境或云服务上运行测试非常有用。以下是一些关于如何设置 Playwright Java 客户端库以支持远程连接的基本步骤:
1. 安装 chromium
1). 更新包管理器:
sudo apt update
2). 安装 Chromium:
sudo apt install chromium-browser -y
2. 启动远程浏览器
通过命令行启动浏览器并指定远程调试端口。
chromium --no-sandbox --headless --disable-gpu --remote-debugging-port=9222
使用 chromium --remote-debugging-port=9222
启动 Chromium 时,它会启动一个 Chromium 实例并在指定端口上开启一个远程调试服务器。例如,启动 Chromium 并监听端口 9222.这个服务器允许通过 WebSocket 连接进行远程控制。
- --no-sandbox 使用 root 命令直接运行
- --headless:开启无头模式 在纯命令行环境下启动 Chromium 并且没有 X11 窗口支持(例如在服务器或无头模式下),你可以使用 无头模式 来启动 Chromium。无头模式允许 Chromium 在没有图形界面的情况下运行。
启动成功后监听的窗口
DevTools listening on ws://127.0.0.1:9222/devtools/browser/86a5e2f5-2d49-4639-bcf2-d6be0cf0c59d
3. 配置 Playwright Java 客户端库连接到远程浏览器
远程调试服务器相当于一个服务端,接受来自客户端的调试命令。客户端则是你的 Playwright Java 应用程序,它通过 WebSocket 连接到这个远程调试服务器并发送命令来控制浏览器。
在 Java 代码中,使用 Playwright Java 客户端库连接到远程浏览器。以下是一个简单的示例代码,展示如何连接到远程浏览器并进行操作:
package com.litongjava.playwright.example;
import java.nio.file.Paths;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
public class RemotePlaywrightExample {
public static void main(String[] args) {
// 创建 Playwright 实例
try (Playwright playwright = Playwright.create()) {
// 连接到远程浏览器实例
BrowserType browserType = playwright.chromium();
Browser browser = browserType.connect("ws://localhost:9222");
// 创建新的浏览器上下文和页面
BrowserContext context = browser.newContext();
Page page = context.newPage();
// 导航到网页
page.navigate("https://example.com");
// 截取页面截图
page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("remote_example.png")));
// 关闭浏览器
browser.close();
}
}
}
Flexmark (Markdown Processor)
1. 简介
Flexmark 是一个功能强大的 Java Markdown 处理库,支持将 HTML 转换为 Markdown。它提供灵活的 API,可以从 HTML 中提取内容并将其转换为符合 Markdown 语法的文本格式。Flexmark 提供了多种扩展和选项,使得在各种 Markdown 转换场景中都能得心应手。
2. 添加依赖
在你的 pom.xml
文件中添加以下 Maven 依赖,确保引入 Flexmark 库:
<dependency>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-all</artifactId>
<version>0.62.2</version>
</dependency>
3. 将 HTML 转换为 Markdown
以下是一个使用 Flexmark 将 HTML 转换为 Markdown 的示例:
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter;
public class HtmlToMarkdown {
public static void main(String[] args) {
// 要转换的 HTML 字符串
String html = "<h1>Hello World</h1><p>This is a paragraph.</p>";
// 创建 HTML 到 Markdown 转换器实例
FlexmarkHtmlConverter converter = FlexmarkHtmlConverter.builder().build();
// 进行转换
String markdown = converter.convert(html);
// 输出转换后的 Markdown 内容
System.out.println(markdown);
}
}
4. 输出结果
运行上述代码后,输出的 Markdown 内容如下:
# Hello World
This is a paragraph.
通过 Flexmark,你可以轻松实现 HTML 到 Markdown 的转换,且转换后的内容格式整洁、易读,适用于博客、文档生成等多个场景。
Playwright-Server 整合方案
1. 简介
在使用 Playwright 进行网页数据抓取时,每次启动 Playwright 都会带来较大的性能开销。为解决这个问题,可以通过在服务启动时初始化 Playwright,并在服务关闭时正确释放资源,从而提升性能。本文介绍如何使用 TioBoot 整合 Playwright,实现高效的网页数据获取服务。
同时 Playwright 的依赖非常多,我们将 Playwright 封装成一个 web 服务,对外提供 Api
2. Playwright 实例管理
为了避免每次请求都重新启动浏览器,Playwright 实例可以在服务启动时初始化,并在需要时使用。
package com.litongjava.playwright.instance;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
public enum PlaywrightBrowser {
INSTANCE;
// 创建 Playwright 实例
public static Playwright playwright = Playwright.create();
public static Browser browser;
static {
// 启动 Chromium 浏览器
BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions().setHeadless(true); // 无头模式
browser = playwright.chromium().launch(launchOptions);
}
public static Browser browser() {
return browser;
}
public static void close() {
browser.close();
playwright.close();
}
public static String getContent(String url) {
BrowserContext context = browser.newContext();
Page page = context.newPage();
page.navigate(url);
String content = page.content();
page.close();
return content;
}
}
3. Playwright 配置类
在服务启动时初始化 Playwright,在服务关闭时自动释放资源,保证高效的资源管理。
package com.litongjava.playwright.config;
import com.litongjava.jfinal.aop.annotation.AConfiguration;
import com.litongjava.jfinal.aop.annotation.AInitialization;
import com.litongjava.playwright.instance.PlaywrightBrowser;
import com.litongjava.tio.boot.server.TioBootServer;
@AConfiguration
public class PlaywrightConfig {
@AInitialization
public void config() {
PlaywrightBrowser.browser(); // 启动浏览器实例
// 服务关闭时释放资源
TioBootServer.me().addDestroyMethod(() -> {
PlaywrightBrowser.close();
});
}
}
说明:
- 使用
@AConfiguration
和@AInitialization
注解,在服务启动时自动创建Browser
实例。 - 将 Playwright 和 Chromium 浏览器的启动设置为无头模式,适合服务器环境。
- 在服务销毁时,利用
TioBootServer
的addDestroyMethod
方法,确保浏览器和 Playwright 实例被正确关闭,避免资源泄漏。
- 使用
4. Playwright 控制器
通过控制器实现网页内容获取和 Markdown 转换功能。
package com.litongjava.playwright.controller;
import com.litongjava.playwright.instance.PlaywrightBrowser;
import com.litongjava.tio.boot.http.TioRequestContext;
import com.litongjava.tio.http.common.HttpResponse;
import com.litongjava.tio.http.server.annotation.RequestPath;
import com.litongjava.tio.http.server.util.Resps;
import lombok.extern.slf4j.Slf4j;
@RequestPath("/playwright")
@Slf4j
public class PlaywrightController {
@RequestPath()
public HttpResponse index(String url) {
log.info("访问的 URL: {}", url);
String content = PlaywrightBrowser.getContent(url);
// 返回网页内容
return Resps.html(TioRequestContext.getResponse(), content);
}
}
package com.litongjava.playwright.controller;
import com.litongjava.playwright.instance.PlaywrightBrowser;
import com.litongjava.tio.boot.http.TioRequestContext;
import com.litongjava.tio.http.common.HttpResponse;
import com.litongjava.tio.http.server.annotation.RequestPath;
import com.litongjava.tio.http.server.util.Resps;
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter;
import lombok.extern.slf4j.Slf4j;
@RequestPath("/markdown")
@Slf4j
public class MarkdownController {
@RequestPath()
public HttpResponse markdown(String url) {
log.info("访问的 URL: {}", url);
String html = PlaywrightBrowser.getContent(url);
// 创建转换器实例
FlexmarkHtmlConverter converter = FlexmarkHtmlConverter.builder().build();
// 将 HTML 转换为 Markdown
String markdown = converter.convert(html);
// 返回网页内容
return Resps.html(TioRequestContext.getResponse(), markdown);
}
}
5. 测试
访问下面的地址进行测试
http://localhost/playwright?url=https://www.sjsu.edu/registrar/calendar/fall-2024.php
http://localhost/markdown?url=https://www.sjsu.edu/registrar/calendar/fall-2024.php
6. 构建 Docker 镜像
为了简化部署,使用 Docker 容器化 Playwright 服务。以下是 Dockerfile 的配置:
# 第一阶段:构建
FROM litongjava/maven:3.8.8-jdk8u391 AS builder
WORKDIR /src
COPY pom.xml /src/
COPY src /src/src
RUN mvn package -DskipTests -Pproduction
# 第二阶段:运行
FROM litongjava/jdk:8u391-stable-slim
WORKDIR /app
COPY --from=builder /src/target/playwright-server-1.0.0.jar /app/
RUN apt update && apt install chromium -y && rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
RUN java -jar /app/playwright-server-1.0.0.jar --download
CMD ["java", "-Xmx900m","-Xms512m","-jar", "playwright-server-1.0.0.jar"]
使用以下命令构建 Docker 镜像:
docker build -t litongjava/playwright-server:1.0.0 .
7. 总结
本文介绍了如何将 Playwright 整合到 TioBoot 中,并通过 Docker 实现高效部署。通过在服务启动时加载 Playwright 实例并在关闭时释放资源,提升了服务的响应性能。此方法特别适合需要频繁进行网页抓取或自动化测试的场景。
这样封装的服务可以有效减少启动开销,适合高并发、低延时的应用场景。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。