public class SerpApi extends Exception {
/**
* 客户端参数
*/
private final Map<String, String> parameter;
/**
* 初始化 gson
*/
private static final Gson gson = new Gson();
/**
* Java 7+ 的 https 客户端实现
*/
private final SerpApiHttp client;
/**
* 默认 HTTP 客户端超时时间
*/
private static final Integer TIME_OUT = 60000;
/**
* 搜索路径
*/
private static final String SEARCH_PATH = "/search";
/***
* 构造函数
*
* @param parameter 默认搜索参数,应包括 {"api_key": "secret_api_key", "engine": "google" }
*/
public SerpApi(Map<String, String> parameter) {
this.parameter = parameter;
this.client = new SerpApiHttp(SEARCH_PATH);
this.client.setHttpConnectionTimeout(TIME_OUT);
}
/***
* 返回原始HTML搜索结果
*
* @param parameter HTML搜索参数
* @return 从客户端引擎获取的原始HTML响应,用于自定义解析
* @throws SerpApiException 封装后端错误消息
*/
public String html(Map<String, String> parameter) throws SerpApiException {
return get("/client", "html", parameter);
}
/***
* 返回JSON格式的搜索结果
*
* @param parameter 自定义搜索参数,可覆盖构造函数中提供的默认参数
* @return JSON对象,包含搜索结果的顶层节点
* @throws SerpApiException 封装后端错误消息
*/
public JsonObject search(Map<String, String> parameter) throws SerpApiException {
return json(SEARCH_PATH, parameter);
}
/***
* 使用Location API返回位置信息
*
* @param parameter 必须包括 {q: "city", limit: 3}
* @return JSON数组,使用Location API返回的位置信息
* @throws SerpApiException 封装后端错误消息
*/
public JsonArray location(Map<String, String> parameter) throws SerpApiException {
String content = get("/locations.json", "json", parameter);
JsonElement element = gson.fromJson(content, JsonElement.class);
return element.getAsJsonArray();
}
/***
* 通过Search Archive API检索搜索结果
*
* @param id 搜索的唯一标识符
* @return 客户端结果的JSON对象
* @throws SerpApiException 封装后端错误消息
*/
public JsonObject searchArchive(String id) throws SerpApiException {
return json("/searches/" + id + ".json", null);
}
/***
* 使用Account API获取账户信息
*
* @param parameter 包含api_key的Map,如果未在默认客户端参数中设置
* @return JSON对象,账户信息
* @throws SerpApiException 封装后端错误消息
*/
public JsonObject account(Map<String, String> parameter) throws SerpApiException {
return json("/account.json", parameter);
}
/***
* 使用Account API获取账户信息
*
* @return JSON对象,账户信息
* @throws SerpApiException 封装后端错误消息
*/
public JsonObject account() throws SerpApiException {
return json("/account.json", null);
}
/***
* 将HTTP内容转换为JsonValue
*
* @param endpoint 原始JSON HTTP响应
* @return 通过gson解析器创建的JSON对象
*/
private JsonObject json(String endpoint, Map<String, String> parameter) throws SerpApiException {
String content = get(endpoint, "json", parameter);
JsonElement element = gson.fromJson(content, JsonElement.class);
return element.getAsJsonObject();
}
/***
* 获取HTTP客户端
*
* @return 客户端实例
*/
public SerpApiHttp getClient() {
return this.client;
}
/***
* 扩展现有参数构建Serp API查询
*
* @param path 后端HTTP路径
* @param output 输出类型(json, html, json_with_images)
* @param parameter 自定义搜索参数,可覆盖默认参数
* @return 格式化参数HashMap
* @throws SerpApiException 封装后端错误消息
*/
public String get(String path, String output, Map<String, String> parameter) throws SerpApiException {
// 更新客户端路径
this.client.path = path;
// 创建HTTP查询
Map<String, String> query = new HashMap(16);
if (path.startsWith("/searches")) {
// 仅保留API_KEY
query.put("api_key", this.parameter.get("api_key"));
} else {
// 合并默认参数
query.putAll(this.parameter);
}
// 用自定义参数覆盖默认参数
if (parameter != null) {
query.putAll(parameter);
}
// 设置当前编程语言
query.put("source", "java");
// 设置输出格式
query.put("output", output);
return this.client.get(query);
}
}