Skip to main content

scrapeunblocker-haystack

Haystack integration for ScrapeUnblocker - fetch pages that block ordinary HTTP requests.

ScrapeUnblocker renders web pages in a real browser behind anti-bot protections such as Cloudflare, DataDome, PerimeterX and Akamai, so your pipeline gets the real content instead of a block page, a captcha, or an empty JavaScript shell.

Installation

pip install scrapeunblocker-haystack

Setup

Get an API key at scrapeunblocker.com and export it:

export SCRAPEUNBLOCKER_API_KEY=<your-api-key>

Both components read that variable by default, or accept a Secret explicitly.

Components

ScrapeUnblockerFetcher

Fetches URLs and returns one Document per page.

from scrapeunblocker_haystack import ScrapeUnblockerFetcher

fetcher = ScrapeUnblockerFetcher()
result = fetcher.run(urls=["https://example.com"])

print(result["documents"][0].content[:200])
Parameter Default Description
api_key SCRAPEUNBLOCKER_API_KEY env var ScrapeUnblocker API key
parsed_data False Return AI-parsed structured JSON instead of raw HTML
proxy_country None Two-letter country code for the exit IP
time_sleep None Seconds to wait after load before capturing
steps None Browser actions to run before the HTML is captured (see below)
list_elements False Return the parsed elements JSON instead of HTML (see below)
base_url https://api.scrapeunblocker.com API base URL
timeout 180 HTTP timeout in seconds
raise_on_failure False Raise instead of skipping a URL that fails

By default a URL that cannot be fetched is logged and skipped, so one bad URL does not discard the rest of the batch.

Browser steps

Pass steps to drive the page in a real browser before its HTML is captured - wait for content to appear, click, type, scroll, and so on. Each step is a dict with an action key plus its parameters:

from scrapeunblocker_haystack import ScrapeUnblockerFetcher

fetcher = ScrapeUnblockerFetcher(
    steps=[
        {"action": "wait_for", "selector": "#results"},
        {"action": "type", "selector": "input#q", "value": "laptops"},
        {"action": "press_key", "value": "Enter"},
        {"action": "wait_for_text", "value": "in stock"},
        {"action": "click", "selector": "button.load-more"},
        {"action": "scroll", "value": "bottom"},
    ]
)
result = fetcher.run(urls=["https://example.com/search"])

Available actions:

Action Parameters
wait_for selector, selector_type? (css|xPath|className|tagName), timeout_ms?
wait_for_text value, timeout_ms?
wait value (milliseconds)
click selector, selector_type?, timeout_ms?
type selector, selector_type?, value, clear?, timeout_ms? (human-like typing)
select selector, selector_type?, value, timeout_ms?
press_key value (Enter|Tab|Escape|Backspace|Delete|Space|Arrow*|Home|End|PageUp|PageDown)
scroll value ("bottom" or an integer pixel offset)

Steps are non-idempotent. If a step fails, the fetch raises StepExecutionError (with step_index, action, selector and reason), which is logged and skipped by default, or re-raised when raise_on_failure=True.

List elements

Set list_elements=True to return the parsed elements JSON ({url, count, elements: [...]}) instead of the page HTML. The JSON is stored as the Document content, and the element count is available in meta["count"]:

fetcher = ScrapeUnblockerFetcher(list_elements=True)
result = fetcher.run(urls=["https://example.com"])

doc = result["documents"][0]
print(doc.meta["count"])          # number of elements
print(doc.content)                # {"url": ..., "count": ..., "elements": [...]}

ScrapeUnblockerWebSearch

Searches Google and returns the organic results as Document objects, with the snippet as content and title / link / position in the metadata.

from scrapeunblocker_haystack import ScrapeUnblockerWebSearch

search = ScrapeUnblockerWebSearch(top_k=5)
result = search.run(query="best web scraping api")

for doc in result["documents"]:
    print(doc.meta["title"], doc.meta["link"])
Parameter Default Description
api_key SCRAPEUNBLOCKER_API_KEY env var ScrapeUnblocker API key
pages_to_check 1 How many result pages to scrape
proxy_country None Two-letter country code for localised results
top_k None Keep at most this many results

In a pipeline

Search the web, fetch the pages behind the results, and answer from them:

from haystack import Pipeline
from haystack.components.builders import ChatPromptBuilder
from haystack.components.converters import HTMLToDocument
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage

from scrapeunblocker_haystack import ScrapeUnblockerFetcher

prompt = [
    ChatMessage.from_user(
        "Answer the question using the pages below.\n\n"
        "{% for doc in documents %}{{ doc.content }}\n{% endfor %}\n"
        "Question: {{ question }}"
    )
]

pipe = Pipeline()
pipe.add_component("fetcher", ScrapeUnblockerFetcher())
pipe.add_component("converter", HTMLToDocument())
pipe.add_component("prompt_builder", ChatPromptBuilder(template=prompt, required_variables="*"))
pipe.add_component("llm", OpenAIChatGenerator())

pipe.connect("fetcher.documents", "converter.sources")
pipe.connect("converter.documents", "prompt_builder.documents")
pipe.connect("prompt_builder.prompt", "llm.messages")

result = pipe.run(
    {
        "fetcher": {"urls": ["https://example.com"]},
        "prompt_builder": {"question": "What is this page about?"},
    }
)
print(result["llm"]["replies"][0].text)

Serialization

Both components implement to_dict() / from_dict(), so pipelines using them can be saved and reloaded. The API key is serialized as a Haystack Secret reference, not as its value.

Links

License

Apache-2.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scrapeunblocker_haystack-0.2.0.tar.gz (12.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scrapeunblocker_haystack-0.2.0-py3-none-any.whl (12.9 kB view details)

Uploaded Python 3

File details

Details for the file scrapeunblocker_haystack-0.2.0.tar.gz.

File metadata

  • Download URL: scrapeunblocker_haystack-0.2.0.tar.gz
  • Upload date:
  • Size: 12.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for scrapeunblocker_haystack-0.2.0.tar.gz
Algorithm Hash digest
SHA256 50e3c54a8e1385a4ffad057d91a69f68bb2b360859949dd3eedebbc3aa5543c7
MD5 d562cd8fba7fcea6f9c43719f6546a7b
BLAKE2b-256 8d6b6bc00cc9a9a924fd8cb721be856b4bade3dbacc75173505ea9e5cc258f02

See more details on using hashes here.

Provenance

The following attestation bundles were made for scrapeunblocker_haystack-0.2.0.tar.gz:

Publisher: publish.yml on ScrapeUnblocker/scrapeunblocker-haystack

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scrapeunblocker_haystack-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for scrapeunblocker_haystack-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4c0694191c9c1f989641a80d85519be090f97c6c64c999a0733588e4f70cf0bd
MD5 dbd55a133f0684d4af0e2d587a9aa490
BLAKE2b-256 2c0039a30dad07815a9ed52d6171231d2c09db29ad80eacc3d8681e1f744d76f

See more details on using hashes here.

Provenance

The following attestation bundles were made for scrapeunblocker_haystack-0.2.0-py3-none-any.whl:

Publisher: publish.yml on ScrapeUnblocker/scrapeunblocker-haystack

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page