searchapi-ruby 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +48 -0
- data/LICENSE.txt +21 -0
- data/README.md +1064 -0
- data/lib/searchapi/client.rb +45 -0
- data/lib/searchapi/configuration.rb +15 -0
- data/lib/searchapi/error.rb +11 -0
- data/lib/searchapi/resource.rb +20 -0
- data/lib/searchapi/resources/airbnb.rb +17 -0
- data/lib/searchapi/resources/amazon_search.rb +17 -0
- data/lib/searchapi/resources/apple_app_store.rb +17 -0
- data/lib/searchapi/resources/baidu.rb +17 -0
- data/lib/searchapi/resources/bing.rb +17 -0
- data/lib/searchapi/resources/bing_images.rb +17 -0
- data/lib/searchapi/resources/bing_videos.rb +17 -0
- data/lib/searchapi/resources/duckduckgo.rb +17 -0
- data/lib/searchapi/resources/ebay_search.rb +18 -0
- data/lib/searchapi/resources/facebook_business_page.rb +25 -0
- data/lib/searchapi/resources/google.rb +17 -0
- data/lib/searchapi/resources/google_about_this_domain.rb +17 -0
- data/lib/searchapi/resources/google_ads_transparency_center.rb +25 -0
- data/lib/searchapi/resources/google_ai_mode.rb +17 -0
- data/lib/searchapi/resources/google_ai_overview.rb +17 -0
- data/lib/searchapi/resources/google_autocomplete.rb +17 -0
- data/lib/searchapi/resources/google_events.rb +17 -0
- data/lib/searchapi/resources/google_finance.rb +17 -0
- data/lib/searchapi/resources/google_flights.rb +23 -0
- data/lib/searchapi/resources/google_forums.rb +17 -0
- data/lib/searchapi/resources/google_hotels.rb +17 -0
- data/lib/searchapi/resources/google_images.rb +17 -0
- data/lib/searchapi/resources/google_jobs.rb +17 -0
- data/lib/searchapi/resources/google_lens.rb +17 -0
- data/lib/searchapi/resources/google_local.rb +17 -0
- data/lib/searchapi/resources/google_maps.rb +30 -0
- data/lib/searchapi/resources/google_news.rb +17 -0
- data/lib/searchapi/resources/google_patents.rb +17 -0
- data/lib/searchapi/resources/google_play_store.rb +33 -0
- data/lib/searchapi/resources/google_rank_tracking.rb +17 -0
- data/lib/searchapi/resources/google_scholar.rb +21 -0
- data/lib/searchapi/resources/google_shopping.rb +17 -0
- data/lib/searchapi/resources/google_shorts.rb +17 -0
- data/lib/searchapi/resources/google_trends.rb +33 -0
- data/lib/searchapi/resources/google_videos.rb +17 -0
- data/lib/searchapi/resources/instagram_profile.rb +17 -0
- data/lib/searchapi/resources/linkedin_ad_library.rb +17 -0
- data/lib/searchapi/resources/meta_ad_library.rb +17 -0
- data/lib/searchapi/resources/naver.rb +17 -0
- data/lib/searchapi/resources/reddit_ad_library.rb +17 -0
- data/lib/searchapi/resources/shein_search.rb +17 -0
- data/lib/searchapi/resources/tiktok_ads_library.rb +17 -0
- data/lib/searchapi/resources/tiktok_profile.rb +17 -0
- data/lib/searchapi/resources/tripadvisor.rb +17 -0
- data/lib/searchapi/resources/walmart_search.rb +17 -0
- data/lib/searchapi/resources/yahoo.rb +17 -0
- data/lib/searchapi/resources/yandex.rb +17 -0
- data/lib/searchapi/resources/yandex_reverse_image.rb +17 -0
- data/lib/searchapi/resources/youtube.rb +17 -0
- data/lib/searchapi/response.rb +25 -0
- data/lib/searchapi/version.rb +5 -0
- data/lib/searchapi.rb +177 -0
- metadata +138 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "faraday"
|
|
4
|
+
require "faraday/retry"
|
|
5
|
+
|
|
6
|
+
module SearchApi
|
|
7
|
+
class Client
|
|
8
|
+
def initialize(config = SearchApi.configuration)
|
|
9
|
+
@config = config
|
|
10
|
+
@connection = build_connection
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get(path, params = {})
|
|
14
|
+
params[:api_key] = @config.api_key
|
|
15
|
+
response = @connection.get(path.delete_prefix("/"), params)
|
|
16
|
+
Response.new(response)
|
|
17
|
+
rescue Faraday::TooManyRequestsError => e
|
|
18
|
+
raise RateLimitError, e.message
|
|
19
|
+
rescue Faraday::UnauthorizedError => e
|
|
20
|
+
raise AuthenticationError, e.message
|
|
21
|
+
rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e
|
|
22
|
+
raise SearchApi::TimeoutError, e.message
|
|
23
|
+
rescue Faraday::ResourceNotFound => e
|
|
24
|
+
raise NotFoundError, e.message
|
|
25
|
+
rescue Faraday::ServerError => e
|
|
26
|
+
raise SearchApi::ServerError, e.message
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def build_connection
|
|
32
|
+
url = @config.base_url
|
|
33
|
+
url += "/" unless url.end_with?("/")
|
|
34
|
+
Faraday.new(url: url) do |f|
|
|
35
|
+
f.request :retry, max: @config.retries,
|
|
36
|
+
retry_statuses: [429, 500, 502, 503]
|
|
37
|
+
f.request :json
|
|
38
|
+
f.response :json, content_type: /\bjson$/
|
|
39
|
+
f.response :raise_error
|
|
40
|
+
f.response :logger, @config.logger if @config.logger
|
|
41
|
+
f.options.timeout = @config.timeout
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
class Configuration
|
|
5
|
+
attr_accessor :api_key, :base_url, :timeout, :retries, :logger
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@api_key = ENV["SEARCHAPI_API_KEY"]
|
|
9
|
+
@base_url = "https://www.searchapi.io/api/v1"
|
|
10
|
+
@timeout = 30
|
|
11
|
+
@retries = 2
|
|
12
|
+
@logger = nil
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
class Error < StandardError; end
|
|
5
|
+
class AuthenticationError < Error; end
|
|
6
|
+
class RateLimitError < Error; end
|
|
7
|
+
class TimeoutError < Error; end
|
|
8
|
+
class NotFoundError < Error; end
|
|
9
|
+
class ValidationError < Error; end
|
|
10
|
+
class ServerError < Error; end
|
|
11
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
class Resource
|
|
5
|
+
def initialize(client = SearchApi.client)
|
|
6
|
+
@client = client
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def get(params = {})
|
|
12
|
+
params[:engine] = engine_name
|
|
13
|
+
@client.get("/search", params)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def engine_name
|
|
17
|
+
raise NotImplementedError
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class Airbnb < Resource
|
|
6
|
+
def search(query, check_in:, check_out:, **params)
|
|
7
|
+
get(q: query, check_in: check_in, check_out: check_out, **params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def engine_name
|
|
13
|
+
"airbnb"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class AppleAppStore < Resource
|
|
6
|
+
def search(term:, **params)
|
|
7
|
+
get(term: term, **params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def engine_name
|
|
13
|
+
"apple_app_store"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class EbaySearch < Resource
|
|
6
|
+
def search(query = nil, **params)
|
|
7
|
+
params[:q] = query if query
|
|
8
|
+
get(**params)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def engine_name
|
|
14
|
+
"ebay_search"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class FacebookBusinessPage < Resource
|
|
6
|
+
def search(**params)
|
|
7
|
+
get(**params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def by_username(username, **params)
|
|
11
|
+
get(username: username, **params)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def by_page_id(page_id, **params)
|
|
15
|
+
get(page_id: page_id, **params)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def engine_name
|
|
21
|
+
"facebook_business_page"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class GoogleAboutThisDomain < Resource
|
|
6
|
+
def search(domain:, **params)
|
|
7
|
+
get(domain: domain, **params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def engine_name
|
|
13
|
+
"google_about_this_domain"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class GoogleAdsTransparencyCenter < Resource
|
|
6
|
+
def search(**params)
|
|
7
|
+
get(**params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def by_advertiser(advertiser_id, **params)
|
|
11
|
+
get(advertiser_id: advertiser_id, **params)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def by_domain(domain, **params)
|
|
15
|
+
get(domain: domain, **params)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def engine_name
|
|
21
|
+
"google_ads_transparency_center"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class GoogleAiOverview < Resource
|
|
6
|
+
def search(page_token:, **params)
|
|
7
|
+
get(page_token: page_token, **params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def engine_name
|
|
13
|
+
"google_ai_overview"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class GoogleAutocomplete < Resource
|
|
6
|
+
def search(query, **params)
|
|
7
|
+
get(q: query, **params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def engine_name
|
|
13
|
+
"google_autocomplete"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class GoogleFinance < Resource
|
|
6
|
+
def search(query, **params)
|
|
7
|
+
get(q: query, **params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def engine_name
|
|
13
|
+
"google_finance"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class GoogleFlights < Resource
|
|
6
|
+
def search(from:, to:, outbound_date:, return_date: nil, **params)
|
|
7
|
+
get(
|
|
8
|
+
departure_id: from,
|
|
9
|
+
arrival_id: to,
|
|
10
|
+
outbound_date: outbound_date,
|
|
11
|
+
return_date: return_date,
|
|
12
|
+
**params
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def engine_name
|
|
19
|
+
"google_flights"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class GoogleHotels < Resource
|
|
6
|
+
def search(query, check_in:, check_out:, **params)
|
|
7
|
+
get(q: query, check_in_date: check_in, check_out_date: check_out, **params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def engine_name
|
|
13
|
+
"google_hotels"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class GoogleMaps < Resource
|
|
6
|
+
def search(query, **params)
|
|
7
|
+
get(q: query, **params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def place(data_id:, **params)
|
|
11
|
+
get(data_id: data_id, **params)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def directions(start:, destination:, **params)
|
|
15
|
+
@client.get("/search", {
|
|
16
|
+
engine: "google_maps_directions",
|
|
17
|
+
start_addr: start,
|
|
18
|
+
end_addr: destination,
|
|
19
|
+
**params
|
|
20
|
+
})
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def engine_name
|
|
26
|
+
"google_maps"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class GooglePatents < Resource
|
|
6
|
+
def search(query, **params)
|
|
7
|
+
get(q: query, **params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def engine_name
|
|
13
|
+
"google_patents"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchApi
|
|
4
|
+
module Resources
|
|
5
|
+
class GooglePlayStore < Resource
|
|
6
|
+
def search(store:, **params)
|
|
7
|
+
get(store: store, **params)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def apps(query = nil, **params)
|
|
11
|
+
search(store: "apps", q: query, **params)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def games(query = nil, **params)
|
|
15
|
+
search(store: "games", q: query, **params)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def movies(query = nil, **params)
|
|
19
|
+
search(store: "movies", q: query, **params)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def books(query = nil, **params)
|
|
23
|
+
search(store: "books", q: query, **params)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def engine_name
|
|
29
|
+
"google_play_store"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|