scrape_creators 0.6.0 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36ed3616d4e59159e3241d2a07b743ad39aa63ac4adf93e63c7f51fbd0e8f173
4
- data.tar.gz: 946bcdd67f4f3e9d5b53819c5c15ace2a56a148871ed58844479349507d8ac09
3
+ metadata.gz: 385c61c807a5dd2f2f1d7106b9430991d97ba68d5e894b6675d58d324243e1c3
4
+ data.tar.gz: 6293f02f4f4724cc2e6b1a11447e66c38ac2440db19f2b31b362a1a260757d81
5
5
  SHA512:
6
- metadata.gz: 27340bf2224cccfc9c5b10041e844e2f202765f34faa5d632f9fd04e7e00b1ea22ccbdcba49ee367af7fad54200618fc108c9ae9b202ac14df93713892c34574
7
- data.tar.gz: 8b4fa602579a360b37af6f80847fe923fa3afb6fb165af8862afd2a81d796ebec4bff0068c2ba2c2781b71d26314669b04ddc4d0d29065fc3068b0e424d9d09a
6
+ metadata.gz: 16846f8a031d0629aece90c2b59ae7f59026a4de1507f0e17a35d036b7c18efb185cdc619babf04bbbe1b81dc4b792ce186d576e58dc7cbd8bea8e33098e6d59
7
+ data.tar.gz: e7d80c9c3d21e7b1482776421c9f70ab6a33759ff3e8ec20d674e2b638dd146084917cb4966158b9b2451a8077ea72981f0500b767a9c8a333b407a58ea9f5c7
data/README.md CHANGED
@@ -88,3 +88,21 @@ comments = scraper.comments("https://www.instagram.com/p/DKSMEpKRd6h/")
88
88
  ## License
89
89
 
90
90
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
91
+
92
+ ## Account search
93
+
94
+ ```ruby
95
+ client.search_users("sean walker", source: "instagram")
96
+ client.search_users("sean walker", source: "tiktok")
97
+ client.search_users("sean walker", source: "youtube")
98
+ # => [{ handle: "seanwalker", name: "Sean Walker", avatar_url: "https://..." }]
99
+ ```
100
+
101
+ Returns one page of accounts, deduplicated by handle. YouTube searches channels,
102
+ whose handles can be passed to `posts_page` to fetch Shorts. Results without a
103
+ usable handle are omitted. Blank queries and unsupported sources raise
104
+ `ArgumentError`; unsuccessful API responses raise `ScrapeCreators::APIError`.
105
+
106
+ Endpoints: [Instagram](https://docs.scrapecreators.com/v1/instagram/search/),
107
+ [TikTok](https://docs.scrapecreators.com/v1/tiktok/search/users/),
108
+ [YouTube](https://docs.scrapecreators.com/v1/youtube/search/).
@@ -55,6 +55,38 @@ module ScrapeCreators
55
55
  end
56
56
  end
57
57
 
58
+ def search_users(query, source: INSTAGRAM)
59
+ query = query.to_s.strip
60
+ raise ArgumentError, 'Search query is required' if query.empty?
61
+
62
+ users = case source.to_s
63
+ when INSTAGRAM
64
+ response = get('/v1/instagram/search', query: query)
65
+ search_results(response).dig('data', 'users').to_a.map do |user|
66
+ { handle: user['username'], name: user['full_name'], avatar_url: user['profile_pic_url'] }
67
+ end
68
+ when TIKTOK
69
+ response = get('/v1/tiktok/search/users', query: query, trim: true)
70
+ search_results(response).fetch('users', []).map do |user|
71
+ { handle: user['unique_id'], name: user['nickname'], avatar_url: user.dig('avatar_medium', 'url_list', 0) }
72
+ end
73
+ when YOUTUBE
74
+ response = get('/v1/youtube/search', query: query, type: 'channels')
75
+ search_results(response).fetch('channels', []).map do |channel|
76
+ { handle: channel['handle'], name: channel['title'], avatar_url: channel['thumbnail'] }
77
+ end
78
+ else
79
+ raise ArgumentError, "Unsupported search source: #{source}"
80
+ end
81
+
82
+ users.filter_map do |user|
83
+ handle = user[:handle].to_s.strip.delete_prefix('@')
84
+ next if handle.empty? || handle.match?(%r{[[:space:]/]})
85
+
86
+ user.merge(handle: handle)
87
+ end.uniq { |user| user[:handle].downcase }
88
+ end
89
+
58
90
  def posts(handle, options = {})
59
91
  source = (options[:source] || 'instagram').to_s
60
92
  pages = options[:pages] || options[:max_pages] || 1
@@ -153,6 +185,14 @@ module ScrapeCreators
153
185
 
154
186
  private
155
187
 
188
+ def search_results(response)
189
+ unless response.is_a?(Hash) && response['success'] != false
190
+ raise APIError, 'Account search failed'
191
+ end
192
+
193
+ response
194
+ end
195
+
156
196
  def posts_cursor_param_for(source:)
157
197
  case source.to_s
158
198
  when TIKTOK then 'max_cursor'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ScrapeCreators
4
- VERSION = "0.6.0"
4
+ VERSION = "0.7.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scrape_creators
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - swlkr