scrape_creators 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 81d8fe07ba67037eed200bf86a2a59940e0cd95be484f290deb4bb22d22cc9bf
4
+ data.tar.gz: ddcd4376a7dfd3e345aa8e8382fb218c6f1ab77975648dc21d2d788d0abe8af8
5
+ SHA512:
6
+ metadata.gz: bb3e3c91366fa725e4a4818659f91a28beaf38b23c463dc62bf87837f56b8c831d715d5b9d71996991dbee96843106ba430a0d9056285f62894fdead2dbc3385
7
+ data.tar.gz: 240ce6fb3cb88ade249726749e8eb40c5975204311bcfc8b49e8ccf32fddb0b62c4a1131915cc1eb4a7b85f0a74bc1571aad682e28987ad41a5c5c90a6566d43
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # ScrapeCreators
2
+
3
+ A zero-dependency Ruby client for the [Scrape Creators API](https://docs.scrapecreators.com).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'scrape_creators', '0.1.0'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ $ bundle install
17
+ ```
18
+
19
+ ## Configuration
20
+
21
+ Configure your API key in an initializer (e.g., `config/initializers/scrape_creators.rb`):
22
+
23
+ ```ruby
24
+ ScrapeCreators.configure do |config|
25
+ config.api_key = ENV['SCRAPE_CREATORS_API_KEY']
26
+ end
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ Initialize a client:
32
+
33
+ ```ruby
34
+ scraper = ScrapeCreators::Client.new
35
+ ```
36
+
37
+ ### Fetch Instagram User Posts & Reels
38
+
39
+ ```ruby
40
+ posts = scraper.posts("zuck")
41
+ ```
42
+
43
+ ### Fetch Instagram Post / Reel Info
44
+
45
+ ```ruby
46
+ info = scraper.post("https://www.instagram.com/p/DKSMEpKRd6h/", download_media: true)
47
+ ```
48
+
49
+ ### Fetch Instagram Post / Reel Comments
50
+
51
+ ```ruby
52
+ comments = scraper.comments("https://www.instagram.com/p/DKSMEpKRd6h/")
53
+ ```
54
+
55
+ ## License
56
+
57
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'json'
6
+ require 'zlib'
7
+ require 'stringio'
8
+
9
+ module ScrapeCreators
10
+ class Client
11
+ attr_reader :config, :api_key
12
+
13
+ def initialize(config = nil, api_key: nil)
14
+ @config = config || ScrapeCreators.configuration
15
+ @api_key = api_key || @config.api_key
16
+ end
17
+
18
+ def posts(username_or_handle, options = {})
19
+ params = { handle: username_or_handle }.merge(options)
20
+ res = get("/v2/instagram/user/posts", params)
21
+ res.is_a?(Hash) ? (res["items"] || []) : []
22
+ end
23
+
24
+ def post(url_or_code, options = {})
25
+ url = normalize_url(url_or_code)
26
+ params = { url: url }.merge(options)
27
+ get("/v1/instagram/post", params)
28
+ end
29
+
30
+ def comments(url_or_code, options = {})
31
+ url = normalize_url(url_or_code)
32
+ params = { url: url }.merge(options)
33
+ res = get("/v2/instagram/post/comments", params)
34
+ res.is_a?(Hash) ? (res["comments"] || []) : []
35
+ end
36
+
37
+ def get(endpoint, params = {}, options = {})
38
+ request(endpoint, method: :get, params: params, options: options)
39
+ end
40
+
41
+ def request(endpoint, method: :get, params: {}, options: {})
42
+ current_key = options[:api_key] || api_key
43
+ if current_key.nil? || current_key.to_s.strip.empty?
44
+ raise ConfigurationError, "Scrape Creators API key is missing. Set ENV['SCRAPE_CREATORS_API_KEY'] or configure via ScrapeCreators.configure { |c| c.api_key = '...' }"
45
+ end
46
+
47
+ clean_endpoint = endpoint.to_s.start_with?('/') ? endpoint.to_s : "/#{endpoint}"
48
+ base_url = options[:api_base_url] || config.api_base_url
49
+ url_str = "#{base_url}#{clean_endpoint}"
50
+
51
+ uri = URI.parse(url_str)
52
+
53
+ if method == :get
54
+ uri.query = URI.encode_www_form(params) if params && !params.empty?
55
+ req = Net::HTTP::Get.new(uri.request_uri)
56
+ else
57
+ req = Net::HTTP::Post.new(uri.request_uri)
58
+ req['Content-Type'] = 'application/json'
59
+ req.body = JSON.generate(params) if params && !params.empty?
60
+ end
61
+
62
+ req['x-api-key'] = current_key
63
+ req['Accept'] = 'application/json'
64
+ req['Accept-Encoding'] = 'gzip, deflate'
65
+
66
+ http = Net::HTTP.new(uri.host, uri.port)
67
+ http.use_ssl = (uri.scheme == 'https')
68
+ http.open_timeout = options[:open_timeout] || config.open_timeout
69
+ http.read_timeout = options[:read_timeout] || config.read_timeout
70
+
71
+ res = http.request(req)
72
+ parse_response(res)
73
+ end
74
+
75
+ private
76
+
77
+ def normalize_url(url_or_code)
78
+ str = url_or_code.to_s.strip
79
+ if str.start_with?('http://', 'https://')
80
+ str
81
+ else
82
+ "https://www.instagram.com/p/#{str}/"
83
+ end
84
+ end
85
+
86
+ def parse_response(response)
87
+ body = response.body
88
+
89
+ if response['Content-Encoding'] == 'gzip' && body && !body.empty?
90
+ begin
91
+ body = Zlib::GzipReader.new(StringIO.new(body)).read
92
+ rescue Zlib::Error, Zlib::GzipFile::Error
93
+ # Decompression fallback
94
+ end
95
+ elsif response['Content-Encoding'] == 'deflate' && body && !body.empty?
96
+ begin
97
+ body = Zlib::Inflate.inflate(body)
98
+ rescue Zlib::Error
99
+ # Decompression fallback
100
+ end
101
+ end
102
+
103
+ parsed = begin
104
+ JSON.parse(body)
105
+ rescue JSON::ParserError
106
+ body
107
+ end
108
+
109
+ unless response.is_a?(Net::HTTPSuccess)
110
+ error_msg = if parsed.is_a?(Hash)
111
+ parsed['detail'] || parsed['message'] || parsed['error'] || response.message
112
+ else
113
+ response.message
114
+ end
115
+ raise APIError.new("ScrapeCreators Error (#{response.code}): #{error_msg}", status: response.code.to_i, response_body: body)
116
+ end
117
+
118
+ parsed
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ScrapeCreators
4
+ class Configuration
5
+ attr_accessor :api_key, :api_base_url, :open_timeout, :read_timeout
6
+
7
+ def initialize
8
+ @api_key = ENV['SCRAPE_CREATORS_API_KEY']
9
+ @api_base_url = "https://api.scrapecreators.com"
10
+ @open_timeout = 10
11
+ @read_timeout = 30
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ScrapeCreators
4
+ class Error < StandardError; end
5
+ class ConfigurationError < Error; end
6
+
7
+ class APIError < Error
8
+ attr_reader :status, :response_body
9
+
10
+ def initialize(message, status: nil, response_body: nil)
11
+ super(message)
12
+ @status = status
13
+ @response_body = response_body
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ScrapeCreators
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "scrape_creators/version"
4
+ require_relative "scrape_creators/error"
5
+ require_relative "scrape_creators/configuration"
6
+ require_relative "scrape_creators/client"
7
+
8
+ module ScrapeCreators
9
+ class << self
10
+ def configuration
11
+ @configuration ||= Configuration.new
12
+ end
13
+
14
+ def configuration=(config)
15
+ @configuration = config
16
+ end
17
+
18
+ def configure
19
+ yield(configuration)
20
+ end
21
+
22
+ def reset
23
+ @configuration = Configuration.new
24
+ end
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scrape_creators
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Substation
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Ruby client for Scrape Creators API (https://scrapecreators.com) to fetch
13
+ social media profile, posts, reels, and comments.
14
+ executables: []
15
+ extensions: []
16
+ extra_rdoc_files: []
17
+ files:
18
+ - README.md
19
+ - lib/scrape_creators.rb
20
+ - lib/scrape_creators/client.rb
21
+ - lib/scrape_creators/configuration.rb
22
+ - lib/scrape_creators/error.rb
23
+ - lib/scrape_creators/version.rb
24
+ homepage: https://github.com/getletterpress/scrape_creators
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 3.0.0
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubygems_version: 3.6.9
43
+ specification_version: 4
44
+ summary: Zero-dependency Ruby client for Scrape Creators API
45
+ test_files: []