-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathREADME.md.erb
More file actions
342 lines (252 loc) · 11.9 KB
/
README.md.erb
File metadata and controls
342 lines (252 loc) · 11.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
<%-
def snippet(format, path)
lines = File.new(path).readlines
stop = lines.find_index do |line|
next false if line.lstrip.start_with?('//')
line.match?(/\bassert(True|NotNull)\s*\(/)
end
if stop.nil?
raise "No assertTrue/assertNotNull found in #{path}"
end
slice = lines[23..stop-1]
slice << "System.out.println(results.toString());"
buf = slice.map { |l| l.gsub(/(^\s\s\s\s)/, '')}.join
buf.gsub!("System.getenv(\"SERPAPI_KEY\")", "\"your_api_key\"")
%Q(```#{format}\n#{buf}\n```\n\n * source code: [#{path}](https://github.com/serpapi/serpapi-#{format}/blob/master/#{path}))
end
-%>
# SerpApi Java Library
[](https://github.com/serpapi/serpapi-java/actions/workflows/gradle.yml)
[](https://jitpack.io/#serpapi/serpapi-java)
Integrate search data into your Java application. This library is the official wrapper for SerpApi (https://serpapi.com).
SerpApi supports Google, Google Maps, Google Shopping, Baidu, Yandex, Yahoo, eBay, App Stores, and more.
[The full documentation is available here.](https://serpapi.com/search-api)
## Installation
Using Maven / Gradle.
Edit your `build.gradle` file:
```gradle
repositories {
maven { url "https://jitpack.io" }
}
dependencies {
implementation 'com.github.serpapi:serpapi-java:1.1.0'
}
```
To list all available versions:
https://jitpack.io/api/builds/com.github.serpapi/serpapi-java
or you can download the jar file from https://github.com/serpapi/serpapi-java/releases
Note: JitPack builds Maven artifacts from GitHub releases and tags.
## Usage
To try the library quickly, use the demo project:
```bash
git clone https://github.com/serpapi/serpapi-java.git
cd serpapi-java/demo
make all SERPAPI_KEY='<your private key>'
```
Use quotes if your key contains shell-special characters. You need a SerpApi account to obtain a key: https://serpapi.com/dashboard
`demo/src/main/java/demo/App.java`:
```javapublic
class App {
public static void main(String[] args) {
String apiKey = System.getenv("SERPAPI_KEY");
// set search location
String location = "Austin,Texas";
String engine = "google";
System.out.println("find the first coffee shop in " + location + " using " + engine);
Map<String, String> auth = new HashMap<>();
auth.put("engine", engine);
auth.put("api_key", apiKey);
// create client
SerpApi serpapi= new SerpApi(auth);
// create search parameters
Map<String, String> parameter = new HashMap<>();
parameter.put("q", "Coffee");
parameter.put("location", location);
// perform search
try {
// get search results
JsonObject data = serpapi.search(parameter);
JsonArray organic = data.getAsJsonArray("organic_results");
JsonObject first = organic.get(0).getAsJsonObject();
System.out.println("First result: " + first.get("title").getAsString() + " (search near " + location + ")");
} catch (SerpApiException e) {
System.out.println("SerpApi request failed.");
e.printStackTrace();
System.exit(1);
}
}
}
```
The [SerpApi.com API Documentation](https://serpapi.com/search-api) contains a list of all the possible parameters that can be passed to the API.
## Documentation
- [SerpApi Search API](https://serpapi.com/search-api) — parameters, engines, and response formats
- After cloning, run `./gradlew javadoc` and open `build/docs/javadoc/index.html` for this library’s Javadoc.
## Requirements
This library uses [Gson](https://github.com/google/gson) for JSON and returns responses as Gson `JsonObject` / `JsonArray`.
**This repository** is built and tested with **JDK 21** and the **Gradle wrapper** (`./gradlew`, currently Gradle 8.5). Use the wrapper so you do not need a separate Gradle install.
**Consumers** of the JitPack artifact should run a JVM whose version is at least the **bytecode level** of the release you depend on (releases from this branch target **Java 21**).
### Location API
```java
SerpApi serpapi = new SerpApi();
Map<String, String> parameter = new HashMap<String, String>();
parameter.put("q", "Austin");
parameter.put("limit", "3");
JsonArray location = serpapi.location(parameter);
System.out.println(location.get(0).getAsJsonObject().get("name").getAsString());
// Prints the first matching name among up to 3 results (see LocationApiTest for a JUnit example).
```
[LocationApiTest.java](https://github.com/serpapi/serpapi-java/blob/master/src/test/java/serpapi/LocationApiTest.java)
### Search Archive API
Run a search to obtain a `search_id`.
```java
Map<String, String> auth = new HashMap<>();
auth.put("api_key", "your_api_key");
SerpApi serpapi = new SerpApi(auth);
Map<String, String> parameter = new HashMap<>();
parameter.put("q", "Coffee");
parameter.put("location", "Austin, Texas, United States");
parameter.put("hl", "en");
parameter.put("gl", "us");
parameter.put("google_domain", "google.com");
parameter.put("safe", "active");
parameter.put("start", "10");
parameter.put("device", "desktop");
JsonObject results = serpapi.search(parameter);
```
Retrieve the same search from the archive:
```java
// now search in the archive
String id = results.getAsJsonObject("search_metadata").getAsJsonPrimitive("id").getAsString();
// retrieve search from the archive with speed for free
JsonObject archive = serpapi.searchArchive(id);
System.out.println(archive.toString());
```
The archived JSON matches the original search result. In tests, the key is supplied via `System.getenv("SERPAPI_KEY")`; see `SerpApiTest.java`.
[SerpApiTest.java](https://github.com/serpapi/serpapi-java/blob/master/src/test/java/serpapi/SerpApiTest.java)
### Account API
```java
Map<String, String> parameter = new HashMap<>();
parameter.put("api_key", "your_api_key");
SerpApi serpapi = new SerpApi(parameter);
JsonObject account = serpapi.account();
System.out.println(account.toString());
```
it prints your account information.
[AccountApiTest.java](https://github.com/serpapi/serpapi-java/blob/master/src/test/java/serpapi/AccountApiTest.java)
## Examples in Java
### Search bing
<%= snippet('java', 'src/test/java/serpapi/example/BingTest.java') %>
see: [https://serpapi.com/bing-search-api](https://serpapi.com/bing-search-api)
### Search baidu
<%= snippet('java', 'src/test/java/serpapi/example/BaiduTest.java') %>
see: [https://serpapi.com/baidu-search-api](https://serpapi.com/baidu-search-api)
### Search yahoo
<%= snippet('java', 'src/test/java/serpapi/example/YahooTest.java') %>
see: [https://serpapi.com/yahoo-search-api](https://serpapi.com/yahoo-search-api)
### Search youtube
<%= snippet('java', 'src/test/java/serpapi/example/YoutubeTest.java') %>
see: [https://serpapi.com/youtube-search-api](https://serpapi.com/youtube-search-api)
### Search walmart
<%= snippet('java', 'src/test/java/serpapi/example/WalmartTest.java') %>
see: [https://serpapi.com/walmart-search-api](https://serpapi.com/walmart-search-api)
### Search ebay
<%= snippet('java', 'src/test/java/serpapi/example/EbayTest.java') %>
see: [https://serpapi.com/ebay-search-api](https://serpapi.com/ebay-search-api)
### Search naver
<%= snippet('java', 'src/test/java/serpapi/example/NaverTest.java') %>
see: [https://serpapi.com/naver-search-api](https://serpapi.com/naver-search-api)
### Search home depot
<%= snippet('java', 'src/test/java/serpapi/example/HomeDepotTest.java') %>
see: [https://serpapi.com/home-depot-search-api](https://serpapi.com/home-depot-search-api)
### Search apple app store
<%= snippet('java', 'src/test/java/serpapi/example/AppleAppStoreTest.java') %>
see: [https://serpapi.com/apple-app-store](https://serpapi.com/apple-app-store)
### Search duckduckgo
<%= snippet('java', 'src/test/java/serpapi/example/DuckduckgoTest.java') %>
see: [https://serpapi.com/duckduckgo-search-api](https://serpapi.com/duckduckgo-search-api)
### Search google
<%= snippet('java', 'src/test/java/serpapi/example/GoogleTest.java') %>
see: [https://serpapi.com/search-api](https://serpapi.com/search-api)
### Search google scholar
<%= snippet('java', 'src/test/java/serpapi/example/GoogleScholarTest.java') %>
see: [https://serpapi.com/google-scholar-api](https://serpapi.com/google-scholar-api)
### Search google autocomplete
<%= snippet('java', 'src/test/java/serpapi/example/GoogleAutocompleteTest.java') %>
see: [https://serpapi.com/google-autocomplete-api](https://serpapi.com/google-autocomplete-api)
### Search google product
```java
// setup serpapi client
Map<String, String> auth = new HashMap<>();
auth.put("api_key", "your_api_key");
SerpApi client = new SerpApi(auth);
// run search
Map<String, String> parameter = new HashMap<>();
parameter.put("engine", "google_product");
parameter.put("q", "coffee");
parameter.put("product_id", "4887235756540435899");
JsonObject results = client.search(parameter);
System.out.println(results.toString());
```
* source code: [src/test/java/serpapi/example/GoogleProductTest.java](https://github.com/serpapi/serpapi-java/blob/master/src/test/java/serpapi/example/GoogleProductTest.java)
see: [https://serpapi.com/google-product-api](https://serpapi.com/google-product-api)
### Search google reverse image
<%= snippet('java', 'src/test/java/serpapi/example/GoogleReverseImageTest.java') %>
see: [https://serpapi.com/google-reverse-image](https://serpapi.com/google-reverse-image)
### Search google events
<%= snippet('java', 'src/test/java/serpapi/example/GoogleEventsTest.java') %>
see: [https://serpapi.com/google-events-api](https://serpapi.com/google-events-api)
### Search google maps
<%= snippet('java', 'src/test/java/serpapi/example/GoogleMapsTest.java') %>
see: [https://serpapi.com/google-maps-api](https://serpapi.com/google-maps-api)
### Search google jobs
<%= snippet('java', 'src/test/java/serpapi/example/GoogleJobsTest.java') %>
see: [https://serpapi.com/google-jobs-api](https://serpapi.com/google-jobs-api)
### Search google play
<%= snippet('java', 'src/test/java/serpapi/example/GooglePlayTest.java') %>
see: [https://serpapi.com/google-play-api](https://serpapi.com/google-play-api)
### Search google images
<%= snippet('java', 'src/test/java/serpapi/example/GoogleImagesTest.java') %>
see: [https://serpapi.com/images-results](https://serpapi.com/images-results)
### Contributing
We use JUnit, **GitHub Actions** (see [workflow](https://github.com/serpapi/serpapi-java/blob/master/.github/workflows/gradle.yml)), and Gradle.
Run the full test suite locally (integration tests call the live API when a key is present):
```bash
export SERPAPI_KEY='your_key' # optional: without it, many tests skip; some tests require the key and will fail if unset
./gradlew test
```
Regenerate `README.md` from the template after editing examples:
```bash
make readme # requires Ruby `erb`
```
#### How to build from source
Clone the repository:
```bash
git clone https://github.com/serpapi/serpapi-java.git
cd serpapi-java
```
Build (use the wrapper):
```bash
./gradlew build
```
The main library JAR is under `build/libs/` (for example `serpapi-1.1.0.jar`, name follows `version` in `build.gradle`). Copy it into your project’s `lib/` directory if you are not using Maven/Gradle dependency resolution.
## TLS / HTTPS and older JVMs
### Symptom
`javax.net.ssl.SSLHandshakeException`
### Cause
SerpApi is served over **HTTPS (TLS)**. Very old JRE/JDK builds may lack the TLS versions or cipher suites required to connect.
### Solution
Use a **current JDK** (this project is tested on **JDK 21**). On macOS you can select an installed JDK, for example:
```sh
/usr/libexec/java_home -V
export JAVA_HOME=$(/usr/libexec/java_home -v 21)
java -version
```
On Windows, install a current JDK from your vendor and point `JAVA_HOME` at it.
### Inspiration
* https://www.baeldung.com/java-http-request
* https://github.com/google/gson
## License
MIT license
## Changelog
- 1.1.0 — Java 21, Gradle 8.x; ongoing API and example updates
- 1.0.0 — Revisit API naming and align the client with serpapi.com