scrapeunblocker-haystack 0.4.0__tar.gz → 0.4.2__tar.gz

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.
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.2
4
+
5
+ - `ScrapeUnblockerWebSearch` adds `sitelinks` (the extra links under a result:
6
+ `title`, `url`, `description`), `rating` (`value`, `max`, `reviews`, `url`)
7
+ and `rich_snippet` (the facts line under the snippet) to each Document's
8
+ metadata, from the new `/serpApi` fields.
9
+
10
+ ## 0.4.1
11
+
12
+ - `ScrapeUnblockerWebSearch` adds `displayed_url`, `domain`, `source` (the
13
+ site's name) and `date` to each Document's metadata. The API now returns
14
+ every organic result with its real URL, also those Google shows without a
15
+ snippet; such a Document's content is the result's title.
16
+
3
17
  ## 0.4.0
4
18
 
5
19
  - `ScrapeUnblockerFetcher` can return pages as clean Markdown for LLMs and RAG.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: scrapeunblocker-haystack
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Haystack integration for ScrapeUnblocker - scrape pages behind anti-bot protections
5
5
  Project-URL: Homepage, https://www.scrapeunblocker.com
6
6
  Project-URL: Documentation, https://docs.scrapeunblocker.com
@@ -69,7 +69,7 @@ print(result["documents"][0].content[:200])
69
69
  | --- | --- | --- |
70
70
  | `api_key` | `SCRAPEUNBLOCKER_API_KEY` env var | ScrapeUnblocker API key |
71
71
  | `parsed_data` | `False` | Return AI-parsed structured JSON instead of raw HTML |
72
- | `proxy_country` | `None` | Two-letter country code for the exit IP |
72
+ | `proxy_country` | `None` | Two-letter country code of the country the request is made from |
73
73
  | `time_sleep` | `None` | Seconds to wait after load before capturing |
74
74
  | `steps` | `None` | Browser actions to run before the HTML is captured (see below) |
75
75
  | `list_elements` | `False` | Return the parsed elements JSON instead of HTML (see below) |
@@ -185,7 +185,9 @@ print(doc.content) # {"url": ..., "count": ..., "elements": [...]
185
185
  ### ScrapeUnblockerWebSearch
186
186
 
187
187
  Searches Google and returns the organic results as `Document` objects, with the
188
- snippet as content and `title` / `link` / `position` in the metadata.
188
+ snippet as content and `title` / `link` / `position` / `displayed_url` / `domain` /
189
+ `source` (the site's name) / `date` / `sitelinks` / `rating` / `rich_snippet` (the
190
+ facts line under the snippet) in the metadata.
189
191
 
190
192
  ```python
191
193
  from scrapeunblocker_haystack import ScrapeUnblockerWebSearch
@@ -44,7 +44,7 @@ print(result["documents"][0].content[:200])
44
44
  | --- | --- | --- |
45
45
  | `api_key` | `SCRAPEUNBLOCKER_API_KEY` env var | ScrapeUnblocker API key |
46
46
  | `parsed_data` | `False` | Return AI-parsed structured JSON instead of raw HTML |
47
- | `proxy_country` | `None` | Two-letter country code for the exit IP |
47
+ | `proxy_country` | `None` | Two-letter country code of the country the request is made from |
48
48
  | `time_sleep` | `None` | Seconds to wait after load before capturing |
49
49
  | `steps` | `None` | Browser actions to run before the HTML is captured (see below) |
50
50
  | `list_elements` | `False` | Return the parsed elements JSON instead of HTML (see below) |
@@ -160,7 +160,9 @@ print(doc.content) # {"url": ..., "count": ..., "elements": [...]
160
160
  ### ScrapeUnblockerWebSearch
161
161
 
162
162
  Searches Google and returns the organic results as `Document` objects, with the
163
- snippet as content and `title` / `link` / `position` in the metadata.
163
+ snippet as content and `title` / `link` / `position` / `displayed_url` / `domain` /
164
+ `source` (the site's name) / `date` / `sitelinks` / `rating` / `rich_snippet` (the
165
+ facts line under the snippet) in the metadata.
164
166
 
165
167
  ```python
166
168
  from scrapeunblocker_haystack import ScrapeUnblockerWebSearch
@@ -17,8 +17,9 @@ class ScrapeUnblockerWebSearch:
17
17
  """
18
18
  Searches Google through the ScrapeUnblocker API and returns the organic results.
19
19
 
20
- Each result becomes a Document whose content is the snippet, with the title,
21
- link and position in the metadata.
20
+ Each result becomes a Document whose content is the snippet (the title when
21
+ Google shows none), with the title, link, position, displayed URL, domain,
22
+ site name, date, sitelinks, star rating and facts line in the metadata.
22
23
 
23
24
  ### Usage example
24
25
 
@@ -107,6 +108,13 @@ class ScrapeUnblockerWebSearch:
107
108
  "title": result.get("title"),
108
109
  "link": result.get("url"),
109
110
  "position": result.get("position"),
111
+ "displayed_url": result.get("displayedUrl"),
112
+ "domain": result.get("domain"),
113
+ "source": result.get("source"),
114
+ "date": result.get("date"),
115
+ "sitelinks": result.get("sitelinks") or [],
116
+ "rating": result.get("rating"),
117
+ "rich_snippet": result.get("richSnippet"),
110
118
  "query": query,
111
119
  },
112
120
  )
@@ -0,0 +1 @@
1
+ __version__ = "0.4.2"
@@ -211,7 +211,12 @@ class TestWebSearch:
211
211
  mock_post.return_value = _response(
212
212
  json_data={
213
213
  "organic": [
214
- {"title": "First", "url": "https://a.com", "description": "snippet a", "position": "1"},
214
+ {"title": "First", "url": "https://a.com", "description": "snippet a", "position": "1",
215
+ "displayedUrl": "https://a.com › docs", "domain": "a.com", "source": "A",
216
+ "date": "Oct 2, 2026",
217
+ "sitelinks": [{"title": "Docs", "url": "https://a.com/docs", "description": None}],
218
+ "rating": {"value": 4.5, "max": 5.0, "reviews": 120, "url": None},
219
+ "richSnippet": "4.5 (120) · Free"},
215
220
  {"title": "Second", "url": "https://b.com", "description": "snippet b", "position": "2"},
216
221
  ]
217
222
  }
@@ -225,6 +230,15 @@ class TestWebSearch:
225
230
  assert result["documents"][0].meta["title"] == "First"
226
231
  assert result["documents"][0].meta["link"] == "https://a.com"
227
232
  assert result["documents"][0].meta["query"] == "test query"
233
+ assert result["documents"][0].meta["domain"] == "a.com"
234
+ assert result["documents"][0].meta["source"] == "A"
235
+ assert result["documents"][0].meta["date"] == "Oct 2, 2026"
236
+ assert result["documents"][1].meta["date"] is None
237
+ assert result["documents"][0].meta["sitelinks"][0]["url"] == "https://a.com/docs"
238
+ assert result["documents"][0].meta["rating"]["value"] == 4.5
239
+ assert result["documents"][0].meta["rich_snippet"] == "4.5 (120) · Free"
240
+ assert result["documents"][1].meta["sitelinks"] == []
241
+ assert result["documents"][1].meta["rating"] is None
228
242
 
229
243
  _, kwargs = mock_post.call_args
230
244
  assert kwargs["params"]["keyword"] == "test query"
@@ -1 +0,0 @@
1
- __version__ = "0.4.0"