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.
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/CHANGELOG.md +14 -0
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/PKG-INFO +5 -3
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/README.md +4 -2
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/src/scrapeunblocker_haystack/search.py +10 -2
- scrapeunblocker_haystack-0.4.2/src/scrapeunblocker_haystack/version.py +1 -0
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/tests/test_components.py +15 -1
- scrapeunblocker_haystack-0.4.0/src/scrapeunblocker_haystack/version.py +0 -1
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/.github/workflows/publish.yml +0 -0
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/.github/workflows/test.yml +0 -0
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/.gitignore +0 -0
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/LICENSE +0 -0
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/pyproject.toml +0 -0
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/src/scrapeunblocker_haystack/__init__.py +0 -0
- {scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/src/scrapeunblocker_haystack/fetcher.py +0 -0
|
@@ -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.
|
|
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
|
|
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`
|
|
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
|
|
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`
|
|
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
|
|
21
|
-
|
|
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"
|
{scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/.github/workflows/publish.yml
RENAMED
|
File without changes
|
{scrapeunblocker_haystack-0.4.0 → scrapeunblocker_haystack-0.4.2}/.github/workflows/test.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|