|
|
@@ -0,0 +1,139 @@
|
|
|
+package cn.iocoder.yudao.module.ai.service.websearch;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.http.HttpRequest;
|
|
|
+import cn.hutool.http.HttpResponse;
|
|
|
+import cn.hutool.json.JSONArray;
|
|
|
+import cn.hutool.json.JSONObject;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import cn.iocoder.yudao.module.ai.service.websearch.vo.WebSearchRespVO;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Bing Web 搜索实现类
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+public class WebSearchServiceImpl implements WebSearchService {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * google url
|
|
|
+ */
|
|
|
+ private static final String GOOGLE_URL = "https://google.serper.dev/search";
|
|
|
+ /**
|
|
|
+ * bing url
|
|
|
+ */
|
|
|
+ private static final String BING_URL = "https://api.bing.microsoft.com/v7.0/search";
|
|
|
+ /**
|
|
|
+ * 腾讯搜索 url
|
|
|
+ */
|
|
|
+ private static final String TENCENT_URL = "tms.tencentcloudapi.com";
|
|
|
+
|
|
|
+ @Value("${yudao.web-search.api-key:}")
|
|
|
+ private String bingApiKey;
|
|
|
+
|
|
|
+ @Value("${yudao.web-search.api-key:}")
|
|
|
+ private String googleApiKey;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * bing 搜索
|
|
|
+ *
|
|
|
+ * @param query 搜索关键词
|
|
|
+ * @param count 返回结果数量
|
|
|
+ * @return 搜索结果列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<WebSearchRespVO> bingSearch(String query, Integer count) {
|
|
|
+ if (query == null || query.isEmpty()) {
|
|
|
+ return CollUtil.newArrayList();
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 发送请求
|
|
|
+ HttpResponse response = HttpRequest.get(BING_URL)
|
|
|
+ .header("Ocp-Apim-Subscription-Key", bingApiKey)
|
|
|
+ .form("q", query)
|
|
|
+ .form("count", String.valueOf(count))
|
|
|
+ .form("responseFilter", "Webpages")
|
|
|
+ .form("textFormat", "Raw")
|
|
|
+ .execute();
|
|
|
+
|
|
|
+ // 解析响应
|
|
|
+ String body = response.body();
|
|
|
+ JSONObject json = JSONUtil.parseObj(body);
|
|
|
+
|
|
|
+ // 处理结果
|
|
|
+ List<WebSearchRespVO> results = new ArrayList<>();
|
|
|
+ if (json.containsKey("webPages") && json.getJSONObject("webPages").containsKey("value")) {
|
|
|
+ JSONArray items = json.getJSONObject("webPages").getJSONArray("value");
|
|
|
+ for (int i = 0; i < items.size(); i++) {
|
|
|
+ JSONObject item = items.getJSONObject(i);
|
|
|
+ WebSearchRespVO result = new WebSearchRespVO()
|
|
|
+ .setTitle(item.getStr("name"))
|
|
|
+ .setUrl(item.getStr("url"))
|
|
|
+ .setSnippet(item.getStr("snippet"));
|
|
|
+ results.add(result);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return results;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("[bingSearch][查询({}) 发生异常]", query, e);
|
|
|
+ return CollUtil.newArrayList();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Google 搜索(使用Serper API)
|
|
|
+ *
|
|
|
+ * @param query 搜索关键词
|
|
|
+ * @param count 返回结果数量
|
|
|
+ * @return 搜索结果列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<WebSearchRespVO> googleSearch(String query, Integer count) {
|
|
|
+ if (query == null || query.isEmpty()) {
|
|
|
+ return CollUtil.newArrayList();
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 构建请求体
|
|
|
+ JSONObject payload = new JSONObject();
|
|
|
+ payload.set("q", query);
|
|
|
+ payload.set("gl", "cn");
|
|
|
+ payload.set("num", count);
|
|
|
+
|
|
|
+ // 发送请求
|
|
|
+ HttpResponse response = HttpRequest.post(GOOGLE_URL)
|
|
|
+ .header("X-API-KEY", googleApiKey)
|
|
|
+ .header("Content-Type", "application/json")
|
|
|
+ .body(payload.toString())
|
|
|
+ .execute();
|
|
|
+
|
|
|
+ // 解析响应
|
|
|
+ String body = response.body();
|
|
|
+ JSONObject json = JSONUtil.parseObj(body);
|
|
|
+ JSONArray organicResults = json.getJSONArray("organic");
|
|
|
+
|
|
|
+ // 处理结果
|
|
|
+ List<WebSearchRespVO> results = new ArrayList<>();
|
|
|
+ for (int i = 0; i < organicResults.size(); i++) {
|
|
|
+ JSONObject item = organicResults.getJSONObject(i);
|
|
|
+ WebSearchRespVO result = new WebSearchRespVO()
|
|
|
+ .setTitle(item.getStr("title"))
|
|
|
+ .setUrl(item.getStr("link"))
|
|
|
+ .setSnippet(item.containsKey("snippet") ? item.getStr("snippet") : "");
|
|
|
+ results.add(result);
|
|
|
+ }
|
|
|
+ return results;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("[googleSearch][查询({}) 发生异常]", query, e);
|
|
|
+ return CollUtil.newArrayList();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|