scrapeunblocker 0.11.1 → 0.13.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 +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +24 -2
- data/lib/scrapeunblocker/client.rb +38 -3
- data/lib/scrapeunblocker/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: df0fdd8cb4a59569bb426126e472c5d4139f0ffb8ae38facfed36c6718080975
|
|
4
|
+
data.tar.gz: 11fc29bb559e468c8a8fdeedd94eb68d3555b73746f9a615859b216fa861ce3c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42e64a25aed1a2c912aeff75bae7bacab8d6571bade1549980044744b7e02d855de73e4227b6a7db3c46b95b9c1571257c5423dd8d84c6d95086d22b74d1d4b1
|
|
7
|
+
data.tar.gz: 2105548d2c9e6fa30492b8e425d786e6b32ebdfe23dd3fff97868422e3a5f6fc2676a5d8115c3e6d438c237eb2238145079b628b914c9229cf162f855023bce9
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.13.0 (2026-10-23)
|
|
4
|
+
|
|
5
|
+
- New `get_markdown(url, main_content_only: true, ...)` returns the rendered page as clean Markdown for LLMs, agents and RAG pipelines: headings, lists, tables, absolute links, images with their alt text and code blocks, without scripts, styles, navigation, footers, forms or hidden elements. It sends `markdown=true` to `/getPageSource`, is billed like an HTML call, and returns a UTF-8 `String`.
|
|
6
|
+
- `main_content_only:` (default `true`) keeps only the page's main content, without navigation, site header, footer and sidebars; pass `false` to convert the whole page. The method also takes `proxy_country:`, `time_sleep:`, `method:`, `value:`, `method_timeout:` and `steps:`, like `get_page_source`.
|
|
7
|
+
- A target page that answers 404 or 410 raises `TargetNotFoundError`, as with `get_page_source`; the not-found page, as Markdown, is on `#html`.
|
|
8
|
+
|
|
9
|
+
No breaking changes.
|
|
10
|
+
|
|
11
|
+
## 0.12.0 (2026-10-15)
|
|
12
|
+
|
|
13
|
+
- `google_images` takes `time_range:` (`"hour"`, `"day"`, `"week"`, `"month"` or `"year"`) to return only the images Google found in that recent period, so a query scanned on a schedule returns only what is new. For a fixed window pass `date_from:` and/or `date_to:` (`"YYYY-MM-DD"`) instead; the API answers 400 when `time_range` is combined with either.
|
|
14
|
+
|
|
15
|
+
No breaking changes.
|
|
16
|
+
|
|
3
17
|
## 0.11.1 (2026-10-15)
|
|
4
18
|
|
|
5
19
|
- `get_image` docs: the API now returns the image's original bytes and format (JPEG, PNG, WebP, AVIF, GIF, SVG, ...) instead of a PNG re-encode. The method still returns a binary `String`.
|
data/README.md
CHANGED
|
@@ -62,6 +62,21 @@ html = su.get_page_source(
|
|
|
62
62
|
)
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
+
## Markdown for LLMs
|
|
66
|
+
|
|
67
|
+
Get the rendered page as clean Markdown instead of HTML, ready for an LLM prompt, an agent or a RAG pipeline. Headings, lists, tables, absolute links and images with their alt text are kept; scripts, styles, navigation, footers and forms are dropped. Billed like an HTML call.
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
md = su.get_markdown("https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html")
|
|
71
|
+
puts md # "# A Light in the Attic\n\n£51.77\n..." (a UTF-8 String)
|
|
72
|
+
|
|
73
|
+
# Only the main content by default (no navigation, site header, footer or sidebars).
|
|
74
|
+
# Pass main_content_only: false to convert the whole page:
|
|
75
|
+
full = su.get_markdown("https://example.com", main_content_only: false)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`get_markdown` takes the same `proxy_country:`, `time_sleep:`, `method:` / `value:` / `method_timeout:` and `steps:` options as `get_page_source`. More in the [Markdown guide](https://docs.scrapeunblocker.com/guides/markdown?utm_source=rubygems&utm_medium=integration&utm_campaign=ruby-sdk).
|
|
79
|
+
|
|
65
80
|
## Browser steps
|
|
66
81
|
|
|
67
82
|
Drive the page after it loads with an ordered list of browser actions - fill a form, click through, wait for content, then capture the rendered result. Steps run once in the real browser, in order.
|
|
@@ -174,8 +189,15 @@ local["results"].each { |biz| puts "#{biz['name']} #{biz['rating']} #{biz['addre
|
|
|
174
189
|
```ruby
|
|
175
190
|
images = su.google_images("golden retriever puppy", proxy_country: "US", pages: 3)
|
|
176
191
|
images["results"].each { |img| puts "#{img['imageUrl']} #{img['sourceDomain']} #{img['title']}" }
|
|
192
|
+
|
|
193
|
+
# Only images Google found in the last day (for a daily scan of the same query)
|
|
194
|
+
new_images = su.google_images("eiffel tower", proxy_country: "US", time_range: "day")
|
|
195
|
+
# Or a fixed window: date_from / date_to (YYYY-MM-DD), each one optional
|
|
196
|
+
october = su.google_images("eiffel tower", date_from: "2026-10-01", date_to: "2026-10-07")
|
|
177
197
|
```
|
|
178
198
|
|
|
199
|
+
`time_range` takes `hour`, `day`, `week`, `month` or `year` and cannot be combined with `date_from` / `date_to`.
|
|
200
|
+
|
|
179
201
|
## Meta Ad Library
|
|
180
202
|
|
|
181
203
|
```ruby
|
|
@@ -292,7 +314,7 @@ end
|
|
|
292
314
|
| `NotFoundError` | 404 | What you asked for does not exist - a plugin lookup found nothing |
|
|
293
315
|
| `TargetNotFoundError` | 404 / 410 | The target page itself does not exist; carries `origin_status`, `html`, `destination_url` (subclass of `NotFoundError`, billed) |
|
|
294
316
|
| `BrowserTimeoutError` | 408 | Our browser run timed out before the page was ready |
|
|
295
|
-
| `UnsupportedContentError` | 415 | The URL serves something other than HTML (`get_page_source`) or other than an image (`get_image`) |
|
|
317
|
+
| `UnsupportedContentError` | 415 | The URL serves something other than HTML (`get_page_source`, `get_markdown`) or other than an image (`get_image`) |
|
|
296
318
|
| `ValidationError` | 422 | Missing or wrong-typed parameter; `body` holds the `detail` array |
|
|
297
319
|
| `RateLimitError` | 429 | Too many requests |
|
|
298
320
|
| `UpstreamOutageError` | 503 | The target origin is down |
|
|
@@ -315,7 +337,7 @@ end
|
|
|
315
337
|
|
|
316
338
|
`TargetNotFoundError` subclasses `NotFoundError`, so `rescue ScrapeUnblocker::NotFoundError` catches it too. A 404 without `X-Origin-Status` is the API's own and stays a plain `NotFoundError`.
|
|
317
339
|
|
|
318
|
-
With `get_parsed` the body is the parsed-data JSON (`{"data": {"page_type": "not_found", ...}}`), so `html` is `nil` there; the raw JSON is on `#body`.
|
|
340
|
+
With `get_parsed` the body is the parsed-data JSON (`{"data": {"page_type": "not_found", ...}}`), so `html` is `nil` there; the raw JSON is on `#body`. With `get_markdown` the not-found page on `#html` is Markdown.
|
|
319
341
|
|
|
320
342
|
### No structured data on the page
|
|
321
343
|
|
|
@@ -75,6 +75,35 @@ module ScrapeUnblocker
|
|
|
75
75
|
body
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
+
# Fetch a URL and return the rendered page as clean Markdown (a UTF-8 String).
|
|
79
|
+
#
|
|
80
|
+
# Built for LLMs, agents and RAG pipelines. The page is rendered in a real
|
|
81
|
+
# browser behind the same anti-bot bypass chain as #get_page_source, then
|
|
82
|
+
# converted to Markdown: headings, lists, tables, absolute links, images with
|
|
83
|
+
# their alt text and code blocks, without scripts, styles, navigation,
|
|
84
|
+
# footers, forms or hidden elements. Billed like an HTML call.
|
|
85
|
+
#
|
|
86
|
+
# +main_content_only+ (default true) keeps only the page's main content,
|
|
87
|
+
# without navigation, the site header, footer and sidebars; pass false to
|
|
88
|
+
# convert the whole page. +proxy_country+, +time_sleep+, +method+, +value+,
|
|
89
|
+
# +method_timeout+ and +steps+ work as in #get_page_source.
|
|
90
|
+
#
|
|
91
|
+
# When the target page itself answers 404 or 410 this raises
|
|
92
|
+
# ScrapeUnblocker::TargetNotFoundError (billed; the not-found page, as
|
|
93
|
+
# Markdown, is on #html).
|
|
94
|
+
def get_markdown(url, main_content_only: true, proxy_country: nil, time_sleep: nil, method: nil, value: nil,
|
|
95
|
+
method_timeout: nil, steps: nil)
|
|
96
|
+
body = request("/getPageSource",
|
|
97
|
+
url: url, markdown: true,
|
|
98
|
+
main_content_only: (main_content_only == false ? false : nil),
|
|
99
|
+
proxy_country: proxy_country, time_sleep: time_sleep,
|
|
100
|
+
method: method, value: value, method_timeout: method_timeout,
|
|
101
|
+
steps: (steps ? JSON.generate(steps) : nil))[:body]
|
|
102
|
+
# The API always sends Markdown as UTF-8; Net::HTTP hands the body over
|
|
103
|
+
# as binary, which breaks string operations on non-ASCII text.
|
|
104
|
+
body.dup.force_encoding(Encoding::UTF_8)
|
|
105
|
+
end
|
|
106
|
+
|
|
78
107
|
# Fetch a URL and return structured JSON instead of HTML.
|
|
79
108
|
#
|
|
80
109
|
# A page that rendered but held no structured data comes back as a
|
|
@@ -126,10 +155,16 @@ module ScrapeUnblocker
|
|
|
126
155
|
# +proxy_country+ to target a market (the Google market follows it; +gl+
|
|
127
156
|
# is an optional override), +pages+ (1-5, ~100 results each; each page
|
|
128
157
|
# fetched is billed as one request, see +pagesFetched+) and +max_results+
|
|
129
|
-
# (1-500) to cap the count.
|
|
130
|
-
|
|
158
|
+
# (1-500) to cap the count. +time_range+ ("hour", "day", "week", "month",
|
|
159
|
+
# "year") keeps only the images Google found in that recent period, e.g.
|
|
160
|
+
# the new ones since the last scheduled scan; +date_from+ / +date_to+
|
|
161
|
+
# ("YYYY-MM-DD", each optional) set a fixed window instead. The two forms
|
|
162
|
+
# cannot be combined.
|
|
163
|
+
def google_images(q, proxy_country: nil, pages: nil, gl: nil, max_results: nil,
|
|
164
|
+
time_range: nil, date_from: nil, date_to: nil)
|
|
131
165
|
post_json("/images/google-search",
|
|
132
|
-
q: q, pages: pages, gl: gl, max_results: max_results, proxy_country: proxy_country
|
|
166
|
+
q: q, pages: pages, gl: gl, max_results: max_results, proxy_country: proxy_country,
|
|
167
|
+
time_range: time_range, date_from: date_from, date_to: date_to)
|
|
133
168
|
end
|
|
134
169
|
|
|
135
170
|
# Fetch an advertiser's Meta (Facebook) Ad Library ads and return them as a Hash.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: scrapeunblocker
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.13.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ScrapeUnblocker
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: JS-rendered pages that bypass Cloudflare, DataDome, PerimeterX and Akamai,
|
|
14
14
|
plus Google SERP and 100+ ready-made site plugins (Amazon, Walmart, Zillow, Google
|