crawlbase 1.0.0 → 1.2.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: 50c42144b472e240907828a2656215a7f1e5004f07a3288d3eafca184b4dc16c
4
- data.tar.gz: fdbbd3ebe2a64ecde61e34b94bd5716574d04d5f1bffb5e1a9225f6500b0a793
3
+ metadata.gz: 42efa911e98c21bc83337c2fd34524b205a04520ae7f13d8c90efd8832cadbee
4
+ data.tar.gz: a031d03c6ed8994135a50ae81279a866918e7feba128e630e22f7908d62c6dee
5
5
  SHA512:
6
- metadata.gz: c29927980f6cf82b431c7385e78429802916ebe188a40e789ca17e1c5a63d7183f4f8b5b30d8b9b7bd42c84fa6f1223eda48703cf317395e359a422a88cddfee
7
- data.tar.gz: db7cf49a5dc174920a76bb35fecb92097b61025e3b2f7fb372a7143282fba93edd748763020001b0cdd928da4500cfe1a948e8123a2232a614cbfb399f3a4843
6
+ metadata.gz: ffcd59a906f655aff0010147ab1db09544137344aa987617c544a058d14a3771694a0cf9e641c46cadc36fc42976156a2e1611af9742acc11119a362e4f694b8
7
+ data.tar.gz: 48cddc484f162578332f974b34b1921e7f5429b909bf71389134ec96cf6b0bf54deccd6301371f5680af20394a4b89192194f35986ab70543532d8351dec511c
data/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.2.0] - 2026-07-15
9
+
10
+ ### Added
11
+
12
+ - `cb_status` as the preferred public attribute for Crawlbase status on `Crawlbase::API` (and subclasses) and `Crawlbase::StorageAPI`.
13
+ - Status resolution prefers the `cb_status` response header or JSON field, then falls back to `pc_status` when `cb_status` is absent.
14
+
15
+ ### Deprecated
16
+
17
+ - `pc_status` is deprecated but still supported and returns the same resolved value as `cb_status`. A one-time deprecation warning is emitted when `pc_status` is accessed. Prefer `cb_status`. Removal is planned for a future major release.
18
+
19
+ ### Migration
20
+
21
+ ```ruby
22
+ # Before (deprecated)
23
+ response.pc_status
24
+
25
+ # After (preferred)
26
+ response.cb_status
27
+ ```
data/README.md CHANGED
@@ -34,6 +34,12 @@ You can get a token for free by [creating a Crawlbase account](https://crawlbase
34
34
  api = Crawlbase::API.new(token: 'YOUR_TOKEN')
35
35
  ```
36
36
 
37
+ By default, the timeout for API requests is set to 90 seconds. You can configure a custom timeout by passing a `timeout` option during initialization.
38
+
39
+ ```ruby
40
+ api = Crawlbase::API.new(token: 'YOUR_TOKEN', timeout: 120)
41
+ ```
42
+
37
43
  ### GET requests
38
44
 
39
45
  Pass the url that you want to scrape plus any options from the ones available in the [API documentation](https://crawlbase.com/dashboard/docs).
@@ -50,7 +56,7 @@ begin
50
56
  response = api.get('https://www.facebook.com/britneyspears')
51
57
  puts response.status_code
52
58
  puts response.original_status
53
- puts response.pc_status
59
+ puts response.cb_status
54
60
  puts response.body
55
61
  rescue => exception
56
62
  puts exception.backtrace
@@ -103,7 +109,7 @@ puts response.body
103
109
  If you need to scrape any website built with Javascript like React, Angular, Vue, etc. You just need to pass your javascript token and use the same calls. Note that only `.get` is available for javascript and not `.post`.
104
110
 
105
111
  ```ruby
106
- api = Crawlbase::API.new(token: 'YOUR_JAVASCRIPT_TOKEN' })
112
+ api = Crawlbase::API.new(token: 'YOUR_JAVASCRIPT_TOKEN')
107
113
  ```
108
114
 
109
115
  ```ruby
@@ -119,17 +125,32 @@ response = api.get('https://www.freelancer.com', options: { page_wait: 5000 })
119
125
  puts response.status_code
120
126
  ```
121
127
 
122
- ## Original status
128
+ ## Original status and Crawlbase status
129
+
130
+ You can always get the original status and Crawlbase status from the response. Read the [Crawlbase documentation](https://crawlbase.com/dashboard/docs) to learn more about those statuses.
123
131
 
124
- You can always get the original status and crawlbase status from the response. Read the [Crawlbase documentation](https://crawlbase.com/dashboard/docs) to learn more about those status.
132
+ Prefer `cb_status` for the Crawlbase status. `pc_status` is deprecated but still supported temporarily and returns the same resolved value.
125
133
 
126
134
  ```ruby
127
135
  response = api.get('https://sfbay.craigslist.org/')
128
136
 
129
137
  puts response.original_status
130
- puts response.pc_status
138
+ puts response.cb_status # preferred
139
+ # puts response.pc_status # deprecated; same value as cb_status
131
140
  ```
132
141
 
142
+ ### Migrating from `pc_status` to `cb_status`
143
+
144
+ ```ruby
145
+ # Before (deprecated)
146
+ response.pc_status
147
+
148
+ # After (preferred)
149
+ response.cb_status
150
+ ```
151
+
152
+ The library reads `cb_status` from the API response first, then falls back to `pc_status` if `cb_status` is not present.
153
+
133
154
  ## Scraper API usage
134
155
 
135
156
  Initialize the Scraper API using your normal token and call the `get` method.
@@ -248,7 +269,7 @@ Pass the [url](https://crawlbase.com/docs/storage-api/parameters/#url) that you
248
269
  begin
249
270
  response = storage_api.get('https://www.apple.com')
250
271
  puts response.original_status
251
- puts response.pc_status
272
+ puts response.cb_status
252
273
  puts response.url
253
274
  puts response.status_code
254
275
  puts response.rid
@@ -265,7 +286,7 @@ or you can use the [RID](https://crawlbase.com/docs/storage-api/parameters/#rid)
265
286
  begin
266
287
  response = storage_api.get(RID)
267
288
  puts response.original_status
268
- puts response.pc_status
289
+ puts response.cb_status
269
290
  puts response.url
270
291
  puts response.status_code
271
292
  puts response.rid
@@ -298,7 +319,7 @@ To do a bulk request with a list of RIDs, please send the list of rids as an arr
298
319
  begin
299
320
  response = storage_api.bulk([RID1, RID2, RID3, ...])
300
321
  puts response.original_status
301
- puts response.pc_status
322
+ puts response.cb_status
302
323
  puts response.url
303
324
  puts response.status_code
304
325
  puts response.rid
@@ -357,8 +378,8 @@ The gem is available as open source under the terms of the [MIT License](http://
357
378
 
358
379
  ## Code of Conduct
359
380
 
360
- Everyone interacting in the Crawlbase projects codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/crawlbase-source/crawlbase-ruby/blob/master/CODE_OF_CONDUCT.md).
381
+ Everyone interacting in the Crawlbase project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/crawlbase-source/crawlbase-ruby/blob/master/CODE_OF_CONDUCT.md).
361
382
 
362
383
  ---
363
384
 
364
- Copyright 2023 Crawlbase
385
+ Copyright 2026 Crawlbase
data/crawlbase.gemspec CHANGED
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency "webmock", "~> 3.4"
29
29
  spec.add_development_dependency "bundler", "~> 2.0"
30
30
  spec.add_development_dependency "rake", "~> 12.3.3"
31
+ spec.add_development_dependency "rexml", "~> 3.2"
31
32
  end
data/lib/crawlbase/api.rb CHANGED
@@ -6,23 +6,36 @@ require 'uri'
6
6
 
7
7
  module Crawlbase
8
8
  class API
9
- attr_reader :token, :body, :status_code, :original_status, :pc_status, :url, :storage_url
9
+ # Crawlbase HTTP response code for the API call itself.
10
+ attr_reader :token, :body, :status_code, :original_status, :url, :storage_url, :timeout
11
+
12
+ # Crawlbase status from the response (preferred name for former +pc_status+).
13
+ attr_reader :cb_status
10
14
 
11
15
  INVALID_TOKEN = 'Token is required'
12
16
  INVALID_URL = 'URL is required'
17
+ DEFAULT_TIMEOUT = 90
13
18
 
14
19
  def initialize(options = {})
15
20
  raise INVALID_TOKEN if options[:token].nil?
16
21
 
17
22
  @token = options[:token]
23
+ @timeout = options.fetch(:timeout, DEFAULT_TIMEOUT)
24
+ end
25
+
26
+ # Deprecated: use {#cb_status}. Returns the same resolved Crawlbase status.
27
+ def pc_status
28
+ StatusResolution.warn_pc_status_deprecated
29
+ @pc_status
18
30
  end
19
31
 
20
32
  def get(url, options = {})
21
33
  raise INVALID_URL if url.empty?
22
34
 
23
35
  uri = prepare_uri(url, options)
24
-
25
- response = Net::HTTP.get_response(uri)
36
+ http = build_http(uri)
37
+ request = Net::HTTP::Get.new(uri.request_uri)
38
+ response = http.request(request)
26
39
 
27
40
  prepare_response(response, options[:format])
28
41
 
@@ -33,10 +46,7 @@ module Crawlbase
33
46
  raise INVALID_URL if url.empty?
34
47
 
35
48
  uri = prepare_uri(url, options)
36
-
37
- http = Net::HTTP.new(uri.host, uri.port)
38
-
39
- http.use_ssl = true
49
+ http = build_http(uri)
40
50
 
41
51
  content_type = options[:post_content_type].to_s.include?('json') ? { 'Content-Type': 'text/json' } : nil
42
52
 
@@ -57,6 +67,14 @@ module Crawlbase
57
67
 
58
68
  private
59
69
 
70
+ def build_http(uri)
71
+ http = Net::HTTP.new(uri.host, uri.port)
72
+ http.use_ssl = true
73
+ http.open_timeout = @timeout
74
+ http.read_timeout = @timeout
75
+ http
76
+ end
77
+
60
78
  def base_url
61
79
  'https://api.crawlbase.com'
62
80
  end
@@ -72,7 +90,8 @@ module Crawlbase
72
90
  res = format == 'json' || base_url.include?('/scraper') ? JSON.parse(response.body) : response
73
91
 
74
92
  @original_status = res['original_status'].to_i
75
- @pc_status = res['pc_status'].to_i
93
+ @cb_status = StatusResolution.resolve_cb_status(res)
94
+ @pc_status = @cb_status
76
95
  @url = res['url']
77
96
  @storage_url = res['storage_url']
78
97
  @status_code = response.code.to_i
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crawlbase
4
+ # Resolves Crawlbase status from response headers or JSON bodies.
5
+ # Prefers +cb_status+, falling back to deprecated +pc_status+.
6
+ module StatusResolution
7
+ PC_STATUS_DEPRECATION =
8
+ '[Crawlbase] `pc_status` is deprecated and will be removed in a future major release. Use `cb_status` instead.'
9
+
10
+ module_function
11
+
12
+ def resolve_cb_status(source)
13
+ raw = source['cb_status']
14
+ raw = source['pc_status'] if raw.nil? || raw.to_s.empty?
15
+ raw.to_i
16
+ end
17
+
18
+ def warn_pc_status_deprecated
19
+ return if Crawlbase.instance_variable_get(:@pc_status_deprecation_warned)
20
+
21
+ Crawlbase.instance_variable_set(:@pc_status_deprecation_warned, true)
22
+ warn PC_STATUS_DEPRECATION, uplevel: 1
23
+ end
24
+ end
25
+ end
@@ -6,7 +6,10 @@ require 'uri'
6
6
 
7
7
  module Crawlbase
8
8
  class StorageAPI
9
- attr_reader :token, :original_status, :pc_status, :url, :status_code, :rid, :body, :stored_at
9
+ attr_reader :token, :original_status, :url, :status_code, :rid, :body, :stored_at
10
+
11
+ # Crawlbase status from the response (preferred name for former +pc_status+).
12
+ attr_reader :cb_status
10
13
 
11
14
  INVALID_TOKEN = 'Token is required'
12
15
  INVALID_RID = 'RID is required'
@@ -20,6 +23,12 @@ module Crawlbase
20
23
  @token = options[:token]
21
24
  end
22
25
 
26
+ # Deprecated: use {#cb_status}. Returns the same resolved Crawlbase status.
27
+ def pc_status
28
+ StatusResolution.warn_pc_status_deprecated
29
+ @pc_status
30
+ end
31
+
23
32
  def get(url_or_rid, format = 'html')
24
33
  raise INVALID_URL_OR_RID if url_or_rid.nil? || url_or_rid.empty?
25
34
 
@@ -30,7 +39,8 @@ module Crawlbase
30
39
  res = format == 'json' ? JSON.parse(response.body) : response
31
40
 
32
41
  @original_status = res['original_status'].to_i
33
- @pc_status = res['pc_status'].to_i
42
+ @cb_status = StatusResolution.resolve_cb_status(res)
43
+ @pc_status = @cb_status
34
44
  @url = res['url']
35
45
  @rid = res['rid']
36
46
  @stored_at = res['stored_at']
@@ -50,7 +60,7 @@ module Crawlbase
50
60
  request = Net::HTTP::Delete.new(uri.request_uri)
51
61
  response = http.request(request)
52
62
 
53
- @url, @original_status, @pc_status, @stored_at = nil
63
+ @url, @original_status, @cb_status, @pc_status, @stored_at = nil
54
64
  @status_code = response.code.to_i
55
65
  @rid = rid
56
66
  @body = JSON.parse(response.body)
@@ -71,7 +81,8 @@ module Crawlbase
71
81
  @body = JSON.parse(response.body)
72
82
  @original_status = @body.map { |item| item['original_status'].to_i }
73
83
  @status_code = response.code.to_i
74
- @pc_status = @body.map { |item| item['pc_status'].to_i }
84
+ @cb_status = @body.map { |item| StatusResolution.resolve_cb_status(item) }
85
+ @pc_status = @cb_status
75
86
  @url = @body.map { |item| item['url'] }
76
87
  @rid = @body.map { |item| item['rid'] }
77
88
  @stored_at = @body.map { |item| item['stored_at'] }
@@ -86,7 +97,7 @@ module Crawlbase
86
97
  uri.query = URI.encode_www_form(query_hash)
87
98
 
88
99
  response = Net::HTTP.get_response(uri)
89
- @url, @original_status, @pc_status, @stored_at = nil
100
+ @url, @original_status, @cb_status, @pc_status, @stored_at = nil
90
101
  @status_code = response.code.to_i
91
102
  @body = JSON.parse(response.body)
92
103
  @rid = @body
@@ -99,7 +110,7 @@ module Crawlbase
99
110
  uri.query = URI.encode_www_form(token: token)
100
111
 
101
112
  response = Net::HTTP.get_response(uri)
102
- @url, @original_status, @pc_status, @stored_at = nil
113
+ @url, @original_status, @cb_status, @pc_status, @stored_at = nil
103
114
  @status_code = response.code.to_i
104
115
  @rid = rid
105
116
  @body = JSON.parse(response.body)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Crawlbase
4
- VERSION = '1.0.0'
4
+ VERSION = '1.2.0'
5
5
  end
data/lib/crawlbase.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'crawlbase/version'
4
+ require 'crawlbase/status_resolution'
4
5
  require 'crawlbase/api'
5
6
  require 'crawlbase/scraper_api'
6
7
  require 'crawlbase/leads_api'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crawlbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - crawlbase
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-29 00:00:00.000000000 Z
11
+ date: 2026-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 12.3.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: rexml
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.2'
69
83
  description: Ruby based client for the Crawlbase API that helps developers crawl or
70
84
  scrape thousands of web pages anonymously
71
85
  email:
@@ -75,6 +89,7 @@ extensions: []
75
89
  extra_rdoc_files: []
76
90
  files:
77
91
  - ".gitignore"
92
+ - CHANGELOG.md
78
93
  - CODE_OF_CONDUCT.md
79
94
  - Gemfile
80
95
  - LICENSE.txt
@@ -88,13 +103,14 @@ files:
88
103
  - lib/crawlbase/leads_api.rb
89
104
  - lib/crawlbase/scraper_api.rb
90
105
  - lib/crawlbase/screenshots_api.rb
106
+ - lib/crawlbase/status_resolution.rb
91
107
  - lib/crawlbase/storage_api.rb
92
108
  - lib/crawlbase/version.rb
93
109
  homepage: https://github.com/crawlbase-source/crawlbase-ruby
94
110
  licenses:
95
111
  - MIT
96
112
  metadata: {}
97
- post_install_message:
113
+ post_install_message:
98
114
  rdoc_options: []
99
115
  require_paths:
100
116
  - lib
@@ -109,8 +125,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
125
  - !ruby/object:Gem::Version
110
126
  version: '0'
111
127
  requirements: []
112
- rubygems_version: 3.1.2
113
- signing_key:
128
+ rubygems_version: 3.5.11
129
+ signing_key:
114
130
  specification_version: 4
115
131
  summary: Crawlbase API client for web scraping and crawling
116
132
  test_files: []