搜索+AI

什么是搜索数据

在现代信息时代,获取最新和准确的信息变得尤为重要。然而,大型语言模型的知识库是固定的,无法及时更新所有的新知识和动态信息。为了解决这一问题,搜索数据的使用应运而生。 搜索数据是指从搜索引擎中获取的相关信息和数据,这些数据可以帮助补充大模型的知识缺口。通过结合用户的输入和相关提示词,搜索数据能够为大模型提供最新的背景信息,从而增强其推理和回答问题的能力。

搜索数据示例

  1. 用户输入: "SJSU 2024 年 秋季学期的开学时间是什么?"
  2. 问题重写之后的输入: "SJSU 秋季 2024 开学时间"
  3. 输入搜索引擎: 将重写后的输入放入搜索引擎,返回对应的数据和搜索结果片段。
  4. 相似度计算: 对搜索结果片段与重写后的输入进行相似度计算,找出相似度较高的片段。
  5. 大模型推理: 将较高相似度的片段、用户的输入和意图识别提示词作为一个输入交由大模型推理,最终生成回答。

搜索引擎 Bing API

首先,我们使用 Bing 搜索 API 来获取搜索结果。Bing API 通过一个简单的 HTTP GET 请求来实现搜索功能。我们需要提供一个查询关键词,并附带必要的 API 密钥以进行身份验证。API 返回的结果通常是一个 JSON 对象,其中包含了搜索到的网页、相关的标题以及内容摘要。

具体的实现如下:

  • 使用 HttpUtils 工具类来发送 HTTP 请求,并获取 API 的响应。
  • 使用 FastJson 库来解析 JSON 响应,从中提取出我们感兴趣的字段(如 URL、标题、内容摘要)。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.litongjava.tio.utils.environment.EnvUtils;
import com.litongjava.tio.utils.http.HttpUtils;
import com.litongjava.tio.utils.json.FastJson2Utils;

import okhttp3.Response;

public class AiSearchService {

  private static final String BING_SEARCH_URL = "https://api.bing.microsoft.com/v7.0/search";

  public static List<String> extractKeyWords(String text) {
    // 简单的关键词提取实现
    return Arrays.asList(text.split(" "));
  }

  public List<Map<String, String>> search(String keyword) {
    List<Map<String, String>> results = new ArrayList<>();
    // 使用Bing搜索API进行搜索
    String url = BING_SEARCH_URL + "?q=" + keyword;

    String BING_API_KEY = EnvUtils.get("BING_API_KEY");

    Map<String, String> headers = new HashMap<>();
    headers.put("Ocp-Apim-Subscription-Key", BING_API_KEY);

    try (Response response = HttpUtils.get(url, headers);) {
      if (response.isSuccessful()) {
        String bodyString = response.body().string();
        JSONObject jsonObject = FastJson2Utils.parseObject(bodyString);
        JSONArray items = jsonObject.getJSONObject("webPages").getJSONArray("value");
        for (int i = 0; i < items.size(); i++) {
          JSONObject item = items.getJSONObject(i);
          Map<String, String> result = new HashMap<>();
          result.put("url", item.getString("url"));
          result.put("title", item.getString("name"));
          result.put("snippet", item.getString("snippet"));
          results.add(result);
        }
      } else {
        throw new RuntimeException("Failed to sarech:" + keyword);
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    return results;
  }
}
package com.litongjava.open.chat.services;

import java.util.List;
import java.util.Map;

import org.junit.Test;

import com.litongjava.jfinal.aop.Aop;
import com.litongjava.tio.utils.environment.EnvUtils;
import com.litongjava.tio.utils.json.JsonUtils;

public class AiSearchServiceTest {

  @Test
  public void testSearch() {
    EnvUtils.load();
    List<Map<String, String>> result = Aop.get(AiSearchService.class).search("when is the first day at San Jose State University (SJSU) in Fall 2024");
    System.out.println(JsonUtils.toJson(result));
  }
}

output

[
  {
    "snippet": "Fall 2024 Spring 2025; First Day of Instruction: August 21, 2024: January 23, 2025: Enrollment Census Date: September 18, 2024: February 19, 2025: ... San José State University. SJSU on Facebook; SJSU on Twitter; SJSU on LinkedIn; SJSU on Instagram; SJSU on YouTube; One Washington Square San José, CA 95192; 408-924-1000;",
    "title": "2024-2025 | Class Schedules - San José State University",
    "url": "https://www.sjsu.edu/classes/calendar/2024-2025.php"
  },
  {
    "snippet": "Fall 2024; Winter Session; Spring 2025; ... (First floor of North Garage, enter on 9th Street) Hours: Mon.- Fri: 8:00 a.m. - 5:00 p.m. (\"Visit in Person\" by appointment via Qless) Mailing Address. Office of the Registrar San José State University One Washington Square San Jose, CA 95192-0009. Footer. San José State University.",
    "title": "Calendar | Office of the Registrar - San José State University",
    "url": "https://www.sjsu.edu/registrar/calendar/"
  },
  {
    "snippet": "All future academic calendars are subject to change due to factors beyond campus control. Academic Year Calendar 2025/26 [pdf] Academic Year Calendar 2026/27 [pdf] Academic Year Calendar 2027/28 [pdf]",
    "title": "Academic Calendars | Office of the Provost - San José State University",
    "url": "https://www.sjsu.edu/provost/resources/academic-calendars/index.php"
  },
  {
    "snippet": "Bursar's Office. Academic Scheduling and Space Management Department. San José State University. One Washington Square. San José, CA 95192. 408-924-1000. SJSU Online. Last Updated May 24, 2024. Accessibility.",
    "title": "Calendar | Class Schedules - San José State University",
    "url": "https://www.sjsu.edu/classes/calendar/index.php"
  },
  {
    "snippet": "Deadline. Wed, Jan. 1. Final Deadline for Grade Submission (11:59 pm) Fri, Jan. 10. Academic Standing & Current Semester Grades posted on MySJSU & Transcripts. Fall 2024 Registration calendar, the important deadlines to register, add/ drop deadlines. Enrollment appointment, Advance and Late registration, Grading timeline.",
    "title": "Fall 2024 | Office of the Registrar - San José State University",
    "url": "https://www.sjsu.edu/registrar/calendar/fall-2024.php"
  },
  {
    "snippet": "San José State University online acadmic catalog, a comprehensive source for current information on academic programs, policies, degree requirements, procedures and course offerings. ... University Menu . Go to SJSU homepage. Visit. Campus Tours; Maps; Parking; Silicon Valley; Hammer Theatre; ... Fall 2024 Spring 2025; First Day of Instruction ...",
    "title": "Calendar - San José State University - Modern Campus Catalog™",
    "url": "https://catalog.sjsu.edu/content.php?catoid=15&navoid=5384"
  },
  {
    "snippet": "October 1, 2024 - December 2, 2024. Cal State Apply Application Period. Application Fee $70 (must be paid at the time of submission) December 2024. Financial Aid (FAFSA and CA Dream Act) Application Available. December 2, 2024. Application Deadline. Application Fee $70 (must be paid at the time of submission) March 2, 2025.",
    "title": "Freshman Deadlines | Admissions - San José State University",
    "url": "https://www.sjsu.edu/admissions/freshman/deadlines/index.php"
  },
  {
    "snippet": "Welcome to the start of Fall 2024! As many of you know, Academic Scheduling & Space Management ... and we look forward to your feedback on the new look by sending it to academicscheduling@sjsu.edu. ... San Jose State University One Washington Square, San Jose, CA 95192 408-924-1000. Powered by WordPress & Highwind.",
    "title": "Academic Scheduling & Space Management Update: Planning for Winter ...",
    "url": "https://blogs.sjsu.edu/abso/2024/08/30/academic-scheduling-space-management-update-planning-for-winter-spring-2025-terms/"
  },
  {
    "snippet": "Students interested in the individualized program of study for PORT 1X/Y and PORT 20X/Y must contact the instructor on the first week of classes in CL 412J at 408-924-4022 or duarte.pinheiro@sjsu.edu. Entry into intermediate studies 20A/X requires the equivalent of 1B/Y or permission of the instructor.",
    "title": "Fall 2024 | Class Schedules - San Jose State University",
    "url": "https://www2.sjsu.edu/classes/schedules/subject-notes/fall-2024.php"
  },
  {
    "snippet": "At least 5 years must have elapsed since the semester you want to disregard. You must have at least a 3.0 GPA in your most recent 15 units at SJSU, or 2.5 in the past 30 units, or 2.0 in the past 45 units. No courses or units earned during the semester you want to disregard may be counted toward graduation.",
    "title": "Registration and Attendance - San Jose State University",
    "url": "https://catalog.sjsu.edu/content.php?catoid=15&navoid=5307"
  }
]

Bing 搜索 API 的返回结果包含多个网页信息。通过遍历这些搜索结果,我们可以逐一提取出网页的 URL、标题和摘要。接下来,我们会使用 Playwright 访问这些 URL,并获取网页的详细内容。

playwright

简介

1. 什么是 Playwright

Playwright 是一个用于自动化网页测试和浏览器操作的现代工具,由微软开发。它支持多种浏览器,包括 Chromium、Firefox 和 WebKit,并提供跨浏览器一致的 API。以下是 Playwright 的一些关键特点:

  1. 多浏览器支持:Playwright 支持 Chromium(包括 Google Chrome 和 Microsoft Edge)、Firefox 和 WebKit(包括 Safari)。这使得开发者可以在多个浏览器上进行一致的测试。

  2. 自动化测试:Playwright 提供强大的自动化测试功能,支持测试用例的编写和执行,可以用于端到端(E2E)测试,功能测试和回归测试等。

  3. 丰富的 API:Playwright 拥有一个强大而直观的 API,用于浏览器自动化、页面导航、表单填写、截图、PDF 生成等。

  4. 并行测试:Playwright 支持并行执行测试,这使得测试可以更快完成,从而提高 CI/CD 管道的效率。

  5. 无头模式和有头模式:Playwright 支持无头模式(headless)和有头模式(headful),无头模式下不会打开浏览器窗口,有头模式下则会。

  6. 跨平台:Playwright 可以在 Windows、Mac 和 Linux 上运行,并且可以在本地和 CI 环境中使用。

  7. 自动处理页面同步:Playwright 自动处理页面加载、元素可见性和其他同步问题,减少了开发者手动等待的需求。

  8. 强大的选择器:Playwright 提供多种选择器策略,包括 CSS 选择器、文本选择器、XPath 等,方便定位页面元素。

  9. 网络拦截和模拟:Playwright 允许拦截和模拟网络请求,可以用于测试不同的网络条件和 API 响应。

  10. 截图和视频录制: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 客户端库

  1. 安装 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' // 请检查最新版本
    }
    
  2. 编写 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
  1. 运行测试: 确保您的项目配置正确,并且 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. 简介

Flexmarkopen in new window 是一个功能强大的 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 浏览器的启动设置为无头模式,适合服务器环境。
    • 在服务销毁时,利用 TioBootServeraddDestroyMethod 方法,确保浏览器和 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 实例并在关闭时释放资源,提升了服务的响应性能。此方法特别适合需要频繁进行网页抓取或自动化测试的场景。

这样封装的服务可以有效减少启动开销,适合高并发、低延时的应用场景。

增强检索