-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathREADME.md.erb
More file actions
337 lines (229 loc) · 12 KB
/
Copy pathREADME.md.erb
File metadata and controls
337 lines (229 loc) · 12 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
# SerpApi Ruby Library
[](https://github.com/serpapi/serpapi-ruby/actions/workflows/ci.yml) [](https://badge.fury.io/rb/serpapi)
Integrate search data into your AI workflow, RAG, fine-tuning, or Ruby application using this official [SerpApi Ruby SDK](https://serpapi.com/integrations/ruby). [SerpApi](https://serpapi.com) supports Google, Google Maps, Google Shopping, Baidu, Yandex, Yahoo, eBay, App Stores, and many more.
## Installation
Ruby 2.7 or later is required.
Install the SDK directly with RubyGems:
```bash
gem install serpapi
```
Or add it to your application's `Gemfile`:
```ruby
gem "serpapi"
```
Then install it with Bundler:
```bash
bundle install
```
## Quickstart
[Create a SerpApi account](https://serpapi.com/users/sign_up?plan=free) to get your API key, then store it in an environment variable:
```bash
export SERPAPI_KEY="your_api_key"
```
Run a Google search and access the results as a Ruby `Hash`:
```ruby
require "serpapi"
require "pp"
client = SerpApi::Client.new(
engine: "google",
api_key: ENV.fetch("SERPAPI_KEY")
)
results = client.search(q: "coffee")
pp results[:organic_results]
client.close
```
## Features
- [Asynchronous searches](./demo/demo_async.rb) for submitting non-blocking jobs and retrieving completed results from the Search Archive API.
- [Persistent connections and connection pooling](./demo/demo_thread_pool.rb) for reusing HTTP connections across searches.
- JSON responses as Ruby hashes with `search`, or raw search-engine HTML with `html`.
- SDK methods for the [Location API](https://serpapi.com/locations-api), [Search Archive API](https://serpapi.com/search-archive-api), and [Account API](https://serpapi.com/account-api).
- Configurable HTTP timeouts and symbolized or string JSON keys.
## Configuration
Set defaults when creating a client, then override search parameters in individual calls:
```ruby
client = SerpApi::Client.new(
api_key: ENV.fetch("SERPAPI_KEY"),
engine: "google",
hl: "en",
gl: "us",
persistent: true,
timeout: 120
)
results = client.search(
q: "coffee",
gl: "gb",
async: false,
symbolize_names: true
)
```
| Option | Default | Description |
| --- | --- | --- |
| `api_key` | None | Your SerpApi API key. Use an environment variable rather than committing it to source control. |
| `engine` | None | The search engine used by default, such as `google` or `google_maps`. |
| `persistent` | `true` | Reuses the HTTP connection between requests. Call `client.close` when finished. |
| `timeout` | `120` | Timeout in seconds for non-persistent HTTP requests. |
| `async` | `false` | Submits searches without waiting for them to complete. It can be set on the client or per search. |
| `symbolize_names` | `true` | Returns JSON object keys as symbols. Pass `false` to a search to receive string keys. |
Search-engine-specific parameters can also be supplied when creating the client or calling `search`. Parameters passed to `search` override client defaults.
### Search Asynchronous
Search API features non-blocking search using the option: `async=true`.
- Non-blocking - async=true - a single parent process can handle unlimited concurrent searches.
- Blocking - async=false - many processes must be forked and synchronized to handle concurrent searches. This strategy is I/O usage because each client would hold a network connection.
Search API enables `async` search.
- Non-blocking (`async=true`) : the development is more complex, but this allows handling many simultaneous connections.
- Blocking (`async=false`) : it is easy to write the code but more compute-intensive when the parent process needs to hold many connections.
Here is an example of asynchronous searches using Ruby
```ruby
require 'serpapi'
company_list = %w[meta amazon apple netflix google]
client = SerpApi::Client.new(engine: 'google', async: true, persistent: true, api_key: ENV['SERPAPI_KEY'])
schedule_search = Queue.new
result = nil
company_list.each do |company|
result = client.search(q: company)
puts "#{company}: search results found in cache for: #{company}" if result[:search_metadata][:status] =~ /Cached/
schedule_search.push(result[:search_metadata][:id])
end
puts "Last search submited at: #{result[:search_metadata][:created_at]}"
puts 'wait 10s for all requests to be completed '
sleep(10)
puts 'wait until all searches are cached or success'
until schedule_search.empty?
search_id = schedule_search.pop
search_archived = client.search_archive(search_id)
company = search_archived[:search_parameters][:q]
if search_archived[:search_metadata][:status] =~ /Cached|Success/
puts "#{search_archived[:search_parameters][:q]}: search results found in archive for: #{company}"
next
end
schedule_search.push(search_id)
end
schedule_search.close
puts 'done'
```
* source code: [demo/demo_async.rb](https://github.com/serpapi/serpapi-ruby/blob/master/demo/demo_async.rb)
This code shows a simple solution to batch searches asynchronously into a [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)). Each search may take up to few seconds to complete. By the time the first element pops out of the queue, the search results might already be available in the archive. If not, the `search_archive` method blocks until the search results are available.
## Examples
Here are some examples for some of our most popular APIs. You can find the full list of supported engines and parameters in our [documentation](https://serpapi.com/search-engine-apis).
### Google Shopping
Scrape Google Shopping results with product names, prices, ratings, and merchant information.
```ruby
require 'serpapi'
client = SerpApi::Client.new(engine: 'google_shopping', api_key: ENV['SERPAPI_KEY'])
results = client.search(q: 'Macbook M4')
pp results[:shopping_results]
```
[See documentation](https://serpapi.com/google-shopping-api)
**Google Shopping Light**
A [light variant](https://serpapi.com/google-shopping-light-api) engine called `google_shopping_light` is also available for faster, lower-cost shopping searches.
### Google Images
Scrape Google Images search results, including image URLs, thumbnails, titles, and source pages.
```ruby
require 'serpapi'
client = SerpApi::Client.new(engine: 'google_images', api_key: ENV['SERPAPI_KEY'])
results = client.search(q: 'coffee')
pp results[:images_results]
```
[See documentation](https://serpapi.com/images-results)
**Google Images Light**
A [light variant](https://serpapi.com/google-images-light-api) engine called `google_images_light` is also available for faster, lower-cost image searches.
### Google Trends
Track search interest over time and compare the popularity of search terms.
```ruby
require 'serpapi'
client = SerpApi::Client.new(engine: 'google_trends', api_key: ENV['SERPAPI_KEY'])
results = client.search(q: 'coffee', data_type: 'TIMESERIES')
pp results[:interest_over_time]
```
[See documentation](https://serpapi.com/google-trends-api)
### Google Flights
Search flight routes, schedules, prices, and booking options.
> **Note:** The `google_flights` engine does not use `q`. Specify route and date parameters such as `departure_id`, `arrival_id`, `outbound_date`, and `return_date`.
```ruby
require 'date'
require 'serpapi'
outbound_date = (Date.today + 30).iso8601
return_date = (Date.today + 37).iso8601
client = SerpApi::Client.new(engine: 'google_flights', api_key: ENV['SERPAPI_KEY'])
results = client.search(
departure_id: 'LAX',
arrival_id: 'AUS',
outbound_date: outbound_date,
return_date: return_date
)
flights = results[:best_flights] || results[:other_flights]
pp flights
```
[See documentation](https://serpapi.com/google-flights-api)
### Google AI Mode API
The Google AI Mode API returns AI-generated answers with structured text blocks, references, images, products, and more.
```ruby
require 'serpapi'
client = SerpApi::Client.new(engine: 'google_ai_mode', api_key: ENV['SERPAPI_KEY'])
results = client.search(q: 'best coffee maker')
pp results[:reconstructed_markdown]
```
[See documentation](https://serpapi.com/google-ai-mode-api)
### Bing Search
Scrape Bing web search results, including organic results, ads, related searches, and more.
```ruby
require 'serpapi'
client = SerpApi::Client.new(engine: 'bing', api_key: ENV['SERPAPI_KEY'])
results = client.search(q: 'coffee')
pp results[:organic_results]
```
[See documentation](https://serpapi.com/bing-search-api)
### DuckDuckGo Search
Scrape DuckDuckGo search results, including organic results, ads, knowledge graphs, and related searches.
```ruby
require 'serpapi'
client = SerpApi::Client.new(engine: 'duckduckgo', api_key: ENV['SERPAPI_KEY'])
results = client.search(q: 'coffee')
pp results[:organic_results]
```
[See documentation](https://serpapi.com/duckduckgo-search-api)
### Baidu Search
Scrape Baidu search results, including organic results, answer boxes, and related searches.
```ruby
require 'serpapi'
client = SerpApi::Client.new(engine: 'baidu', api_key: ENV['SERPAPI_KEY'])
results = client.search(q: 'coffee')
pp results[:organic_results]
```
[See documentation](https://serpapi.com/baidu-search-api)
### Amazon Search
Scrape Amazon product search results, including product names, prices, ratings, reviews, and availability.
> **Note:** The `amazon` engine uses the `k` parameter for a keyword search, not `q`.
```ruby
require 'serpapi'
client = SerpApi::Client.new(engine: 'amazon', api_key: ENV['SERPAPI_KEY'])
results = client.search(k: 'coffee')
pp results[:organic_results]
```
[See documentation](https://serpapi.com/amazon-search-api)
## Documentation
SerpApi supports Google Search, Google Maps, Google Shopping, Baidu, Yandex, Yahoo, eBay, Apple App Store, and many other APIs. Browse the [SerpApi documentation](https://serpapi.com/search-api) to find supported APIs and parameters, or use the [Playground](https://serpapi.com/playground) to build a request and generate Ruby code.
Additional SDK resources:
- [Ruby SDK integration page](https://serpapi.com/integrations/ruby)
- [Ruby SDK API reference](https://rubydoc.info/github/serpapi/serpapi-ruby/master)
- [RubyGems package](https://rubygems.org/gems/serpapi)
- [SerpApi status](https://serpapi.com/status)
## Performance
### Ruby 4.0.0 vs 3.4.4 vs Ruby 2.7.8 Performance
| Metric | Ruby 2.7.8 | Ruby 3.4.4 | Ruby 4.0.0 | Improvement (3.4.4 vs 2.7.8) | Improvement (4.0.0 vs 3.4.4) |
|--------|------------|------------|------------|------------------------------|------------------------------|
| **SerpApi Non-Persistent** | 100.93 req/s | 114.97 req/s | 120.09 req/s | **+13.9%** | **+4.5%** |
| **SerpApi Persistent** | 226.82 req/s | 255.07 req/s | 296.05 req/s | **+12.4%** | **+16.1%** |
| **HTTP.rb Non-Persistent** | 270.62 req/s | 294.01 req/s | 319.81 req/s | **+8.6%** | **+8.8%** |
| **HTTP.rb Persistent** | 347.04 req/s | 570.95 req/s | 456.93 req/s | **+64.5%** | **-20.0%** |
### Key Takeaways
1. **Upgrade to Ruby 3.4.4**: Clear performance benefits across all scenarios
2. **Use Persistent Connections**: 2x+ performance improvement in most cases
3. **HTTP.rb Performance**: Particularly benefits from Ruby 3.4.4 with persistent connections
4. **SerpApi Optimization**: Shows consistent ~2.2x improvement with persistent connections regardless of Ruby version
5. **Ruby 4.0.0 Performance**: Shows mixed results with some regressions compared to 3.4.4, particularly for HTTP.rb persistent connections. Ruby 4.0.0 was just released for Christmas 2025, and HTTP.rb has not been optimized for it yet.
The older library (google-search-results-ruby) was performing at 55 req/s on Ruby 2.7.8, which is 2x slower than the current version (serpapi-ruby) on Ruby 3.4.4 or 4.0.0.
**Context** This benchmark was performed on warmup search results using a MacBook Pro 2025 connected via Wi-Fi 6.0 home network on AT&T fiber from Austin, TX (no network optimization).
## Contributing
Contributions are welcome. Make sure to read our [contributing guide](https://github.com/serpapi/serpapi-ruby/blob/master/CONTRIBUTING.md).
© 2026 [SerpApi](https://serpapi.com)