RAG Web Browser - Google Search to Markdown for AI
Eimantas V · @amethyst
Web search and fetch for AI agents and RAG: searches Google and returns the top results as clean Markdown with token counts, or reads any URL. No browser.

About
RAG Web Browser searches Google and returns the top results' pages as clean Markdown, ready for an LLM, a RAG pipeline or an AI agent. Give it a search, a list of searches, or any URL, and get one row per page with its content, metadata and the Google result it came from. No login, no API key, no browser, one flat monthly price.
# What is retrieval augmented generation (RAG)?
Published 21 October 2024
Updated 02 October 2026
By [Ivan Belcic](https://www.ibm.com/think/author/ivan-belcic) and
## What is retrieval augmented generation (RAG)?
Retrieval augmented generation, or RAG, is an architecture for optimizing the performance of an [artificial intelligence (AI)](https://www.ibm.com/think/topics/artificial-intelligence) model by connect...
That is the markdown of Google's result #2 for "what is retrieval augmented generation" (IBM), with tokenCount 3,987 and wordCount 2,309 beside it.
What does RAG Web Browser do?
It gives AI agents and LLM apps the two things a web browsing tool needs: search and read. A search goes to Google (any country, any language, any time range) and the top organic results are fetched in parallel, cleaned down to their main content and converted to Markdown. A URL is read directly. One call returns everything, so an agent spends one tool call instead of a search plus N page fetches.
- Search or read: a Google search (with operators such as
site:,-site:,"exact phrase",after:2026-01-01), a page URL, a bare domain likedocs.apify.com, or a pasted Google search URL. One or thousands per run. - Main content only: menus, sidebars, footers, cookie banners and comment threads are removed, so the tokens you pay your LLM for are the article, the docs or the post. Switch to "Whole page" when you want everything.
- Markdown, plain text, cleaned HTML and links: any combination, at the same price. Tables, code blocks with their language, nested lists and absolute links are kept.
- Made for LLM context windows: every page comes with
tokenCountandwordCount, and an optional character cap cuts each page on a paragraph boundary. - Always the number of pages you asked for: when a result cannot be read (a site that blocks automated visitors, a PDF, a dead link), the next Google result is read in its place.
- Clear errors. Failed pages, skipped sites and empty searches return a row that says why.
- Built for agents and automation: callable as a tool through the Bytewells MCP server, the Bytewells API and schedules.
Why it is fast and cheap
There is no browser. Google's lightweight results page is read over plain HTTP, and each result page is fetched with a real browser's network fingerprint, then parsed and converted in the same process. That is why one search with its pages takes about 3 seconds of run time, why the Actor runs on 1 GB instead of 8 GB, and why a page uses a fraction of the compute a browser needs. A site that does not answer within 4 seconds gets a second request from another IP address, and the first answer wins.
What data can you extract from the web?
| Field | Example | What it is |
|---|---|---|
markdown | # What is RAG?\n\nRetrieval augmented... | The page's content as Markdown (also text, html, links when chosen) |
metadata.url | https://www.ibm.com/think/topics/retrieval-augmented-generation | The page's address after redirects |
metadata.title | What is RAG (Retrieval Augmented Generation)? | IBM | The page's title |
metadata.description | Retrieval augmented generation (RAG) is an architecture... | Meta description |
metadata.publishedAt | 2024-10-31T00:00:00.000Z | Publication date (meta tags or JSON-LD), ISO 8601 |
metadata.author, siteName, languageCode, canonicalUrl, imageUrl, openGraph | en, https://... | The rest of the page's metadata |
searchResult.position | 2 | The page's rank on Google |
searchResult.title, description, displayedUrl, date | What is RAG...? - IBM | The Google result itself, with its snippet |
tokenCount | 3987 | Estimated LLM tokens of the Markdown |
wordCount | 2309 | Words in the content |
contentScope | main | main when narrowed to the main content, page for the whole page |
contentTruncated | false | True when your character cap cut the content |
crawl.httpStatusCode, loadTimeMs, contentType | 200, 1288, text/html | How the page loaded |
input | what is retrieval augmented generation | The search or URL exactly as you entered it |
How to search Google and get pages as Markdown
- Type a search or a URL into Search query or URL (more go under More queries or URLs, one per line).
- Set Results per search (3-5 is typical for an AI agent) and pick the Output formats.
- Click Start. One search with 3 pages takes a few seconds.
- Open the Output tab, or read the dataset as JSON.
How much does it cost?
One flat monthly rental, shown on this page, with a free trial. There is no per-page or per-search fee: read as many pages as you need.
Runs use your credits for compute and any proxy traffic, as every Actor does. Pages load from the platform's own address; Google's results page usually needs the residential proxy, about 10-40 KB a search. When Google refuses every address for a while, the Actor rests and retries the refused searches up to four times, 1-4 minutes apart, so such a run takes longer but uses little more than its idle compute.
Input
{
"query": "best open source vector database",
"maxResults": 5,
"outputFormats": ["markdown"],
"countryCode": "",
"timeRange": "y",
"maxCharsPerPage": 8000
}
| Field | Default | Notes |
|---|---|---|
Search query or URL (query) | what is retrieval augmented generation | A Google search or a page URL; several lines are several queries |
More queries or URLs (queries) | none | Any number, one per line; duplicates are skipped |
Start URLs (startUrls) | none | Pages in the URL-list shape other Actors output, for chaining |
Results per search (maxResults) | 3 | 1-100; Google's further result pages are fetched as needed |
Replace pages that fail (replaceFailedPages) | on | Reads the next result in place of one that cannot be read |
Output formats (outputFormats) | Markdown | Markdown, plain text, HTML (cleaned) and links, any combination |
Content to keep (htmlTransformer) | Main content only | readableText (main content) or none (whole page) |
Max characters per page (maxCharsPerPage) | 0 (no cap) | Cuts Markdown and text on a paragraph boundary |
Remove HTML elements (removeElementsCssSelector) | nav, footer, script, ... | CSS selector of extra elements to drop |
Search from country (countryCode) | United States | Google's gl: results as a person there sees them |
Interface language (languageCode) | the country's | Google's hl |
Results from (timeRange) | any time | Past hour, 24 hours, week, month or year |
Max pages per run (maxItems) | 1000 | Total across all queries |
Time per query (requestTimeoutSecs) | 40 s | Pages still loading then become TIMEOUT rows, so an agent gets its answer in time |
Retries per page (maxRequestRetries) | 1 | Each retry comes from a fresh IP address |
Queries at a time (maxConcurrency) | 5 | Pages of one query are always fetched in parallel |
Proxy for pages (proxyConfiguration) | off | Off: the Actor's own IP, with refused pages retried through the platform's datacenter proxy automatically. On: every page through datacenter proxy or your own proxy URLs |
Debug log (debugMode) | off | Logs every request with its route, status and time |
The input names (query, maxResults, outputFormats, htmlTransformer, removeElementsCssSelector, requestTimeoutSecs, maxRequestRetries, debugMode) and the output fields (searchResult, metadata, markdown, text, html, links, crawl) follow the common RAG web browser format, so an existing integration works unchanged.
Output
Each page read is one row. The Overview view shows query, rank, URL, title, size and Markdown; Search results shows the Google results; Page metadata shows dates and authors; Errors lists what could not be read. Every export includes all fields.
{
"recordType": "item",
"input": "what is retrieval augmented generation",
"searchResult": {
"position": 2,
"title": "What is RAG (Retrieval Augmented Generation)? - IBM",
"description": "Retrieval augmented generation (RAG) is an architecture for optimizing the performance of an artificial intelligence (AI) model by ...",
"url": "https://www.ibm.com/think/topics/retrieval-augmented-generation",
"displayedUrl": "www.ibm.com › think › topics › retrieval-augmented-generation",
"date": "2024-10-21T00:00:00.000Z",
"resultType": "ORGANIC"
},
"metadata": {
"url": "https://www.ibm.com/think/topics/retrieval-augmented-generation",
"title": "What is RAG (Retrieval Augmented Generation)? | IBM",
"description": "Retrieval augmented generation (RAG) is an architecture for optimizing the performance of an artificial intelligence (AI) model by connecting it with external knowledge bases.",
"languageCode": "en",
"canonicalUrl": "https://www.ibm.com/think/topics/retrieval-augmented-generation",
"author": null,
"publishedAt": "2024-10-31T00:00:00.000Z",
"modifiedAt": "2026-10-02T00:00:00.000Z",
"siteName": null,
"imageUrl": "https://www.ibm.com/content/dam/worldwide-content/stock-assets/adb-stk/ul/g/ce/5b/adobestock_451765072.jpeg/_jcr_content/renditions/cq5dam.web.1280.1280.jpeg",
"openGraph": [{ "property": "og:type", "content": "website" }]
},
"markdown": "# What is retrieval augmented generation (RAG)?\n\nPublished 21 October 2024\n\nUpdated 02 October 2026\n\nBy [Ivan Belcic](https://www.ibm.com/think/author/ivan-belcic) ...",
"wordCount": 2309,
"tokenCount": 3987,
"contentTruncated": false,
"contentScope": "main",
"crawl": {
"httpStatusCode": 200,
"httpStatusMessage": "OK",
"loadedAt": "2026-10-29T13:42:45.777Z",
"requestStatus": "handled",
"loadTimeMs": 1288,
"contentType": "text/html"
},
"scrapedAt": "2026-10-29T13:42:44.186Z"
}
A page or search that cannot be read becomes a row with "recordType": "error", the page's url, its searchResult and an errorCode, instead of failing the run:
errorCode | Meaning |
|---|---|
BLOCKED | The site refused automated visitors (HTTP 401/403/429 or a bot check) from every address tried, or is a site known to refuse them (then skipped without a request) |
TIMEOUT | The site did not answer within the time per query |
NOT_FOUND | The page is gone (HTTP 404/410) |
UNSUPPORTED_CONTENT | Not a web page: a PDF, image, video, archive or office file |
HTTP_ERROR / NETWORK / INVALID_URL | The site answered with an error, the connection failed, or the address is malformed |
NO_RESULTS | Google returned no web results for the search |
RATE_LIMITED | Google refused the search from every address this run tried (retried up to four times at the end of the run) |
PARSE_FAILED | The page loaded but could not be read (please report it) |
Tips and limits
- Agents: keep context small. Set Max characters per page (8,000 characters is about 2,000 tokens) and 3-5 results per search. Use
site:in the query to stay on documentation you trust. - No JavaScript is run. Pages that build their text in the browser (some single-page apps) return little content. Most news, docs, blogs, wikis and product pages are served as HTML and read fully. Plain Markdown and text files (
llms.txt, README files) are returned as they are. - Some sites refuse automated visitors from cloud addresses: Reddit, Medium and Stack Overflow always do, so their results are skipped and replaced by the next result. Others (Cloudflare-protected sites) sometimes do; those pages are retried from another IP, then reported as
BLOCKED. - PDFs and office files are not read. They are listed as
UNSUPPORTED_CONTENT. - Web results only. Google's maps, news carousels and AI Overview are not part of the pages read; for full results-page data use the Google Search Results Scraper.
- Google sometimes refuses searches for a few minutes. Refused searches are retried up to four times at the end of the run, 1-4 minutes apart, within the run's timeout; a search that is still refused gets a
RATE_LIMITEDrow: run it again later. URLs you give directly do not depend on Google.
FAQ
Is it legal to scrape Google and websites?
This Actor reads only pages that are publicly available without logging in, the same pages a visitor's browser loads. Pages can still contain personal data, which laws such as the GDPR protect, and some sites' terms restrict automated access. Use the data for a legitimate purpose, respect copyright when you reuse content, and ask a lawyer if you are unsure. Google is a trademark of its owner; this Actor is not affiliated with or endorsed by Google.
Can AI agents use it?
Yes, that is what it is built for. Agents connected to the Bytewells MCP server can add it as a tool: one call searches, reads the pages and returns Markdown with token counts. The input takes a single query, so an agent needs no other parameters.
Can I use it through the API?
Yes. Every run can be started through the Bytewells API (the run-sync endpoint returns the pages in the same call) and its dataset read as JSON. The API is Apify-compatible, so apify-client works with the Bytewells base URL. Runs can also be scheduled and can trigger webhooks.
Can I switch from another RAG web browser?
Yes. The input fields query, maxResults, outputFormats, htmlTransformer, removeElementsCssSelector, requestTimeoutSecs and maxRequestRetries, and the output fields searchResult, metadata, markdown, text, html, links and crawl, use the common format. Additions are on top: batch queries, country, language and time range, token counts, the character cap and page replacement.
Why did I get fewer pages than I asked for?
Google had fewer results than you asked for, every remaining result failed (the error rows say why), the time per query ran out, or Google kept refusing the search through every retry. The log says which, and nothing collected before that is lost.
Related scrapers
- Google Search Results Scraper: the Google results page itself as data: organic results, places, top stories, knowledge panel and related searches, without reading the pages.
- Website Content Crawler for LLMs & RAG: crawl a whole website to Markdown, with boilerplate learned across its pages and ready-to-embed chunks.
Support
A page that comes back empty or wrong, or a site that should work? Report it with the input you used, and it will be looked at quickly.
FAQ
- What does RAG Web Browser return?
- For a search: the top Google results, each fetched and cleaned down to its main content, as Markdown, plain text, cleaned HTML or links, with title, description, URL, token count and word count. A URL or bare domain is read directly.
- Can AI agents use it?
- Yes, it is built for them. Agents connected to the Bytewells MCP server (bytewells.com/docs/mcp) can add it as a tool: one call searches, reads the pages and returns Markdown. The input takes a single query, so an agent needs no other parameters.
- How do I keep the context small for my LLM?
- Set Max characters per page (8,000 characters is about 2,000 tokens) and ask for 3-5 results per search. Use site: in the query to stay on sources you trust. Every page comes with its token count.
- Does it run JavaScript?
- No. Pages that build their text in the browser return little content; most news, docs, blogs, wikis and product pages are served as HTML and read fully. PDFs and office files are not read.
- Why are some results skipped?
- Some sites refuse automated visitors from cloud addresses: Reddit, Medium and Stack Overflow always do. Those results are replaced by the next Google result, so you still get the number of pages you asked for.
- Can I switch from another RAG web browser?
- Yes. The input fields query, maxResults, outputFormats, htmlTransformer, removeElementsCssSelector, requestTimeoutSecs and maxRequestRetries, and the output fields searchResult, metadata, markdown, text, html and links use the common format.
- Can I use it through the API?
- Yes. Start runs through the Bytewells API (bytewells.com/docs/api) and read the pages as JSON; schedules and webhooks work too. The API is Apify-compatible, so apify-client works with the Bytewells base URL.
Input
Preview of the input form. Rent the Actor to fill it in and start runs from the console.
queryA Google search, e.g. "best open-source vector databases" (operators work: site:, -site:, "exact phrase", after:2026-01-01), or the URL of one page to read, e.g. https://docs.apify.com. Several lines are read as several queries.
queriesAny number of further searches or URLs, one per line, read in the same run. Duplicates are skipped.
startUrlsPages to read, in the URL-list shape other Actors output, so a previous Actor's results can be fed straight in. Read like URLs in the fields above.
maxResultsHow many of Google's top organic results to read for each search. 3-5 is typical for an AI agent; up to 100 (Google's further result pages are fetched as needed). Ignored for URLs.
replaceFailedPagesWhen a result cannot be read (the site blocks automated visitors, a PDF, a dead link), read the next Google result in its place, so a search returns as many pages as asked for. The failed result is still listed.
outputFormatsWhat to return for each page: Markdown (best for LLMs), plain text, the cleaned HTML of the content, and the page's links. Any combination.
htmlTransformerMain content (default): the article, docs or post body, without menus, sidebars, footers, cookie banners and comment threads; a page whose text is spread out keeps everything. Whole page: everything except the elements removed below.
maxCharsPerPageCut each page's Markdown and text at this many characters, on a paragraph boundary, to keep an LLM's context small (8,000 characters is about 2,000 tokens). Rows say contentTruncated. 0 = no cap.
removeElementsCssSelectorCSS selector of elements to remove before the content is read, e.g. ".ad, .newsletter". Empty removes nothing extra. Scripts, styles and form controls are always removed.
countryCodeThe country Google searches from (gl): results as a person there sees them. Default: United States.
languageCodeGoogle's interface language (hl), which also steers result language. Default: the country's own language.
timeRangeOnly results Google dates within this period, for fresh news and recent posts.
maxItemsStop after this many pages read in total, across all queries. It also caps how much compute the run uses.
The defaults are tuned for speed and cost. Change them only if pages are blocked or slow.
requestTimeoutSecsTime budget for one query: the Google search and all its pages. Pages still loading when it runs out are returned as TIMEOUT rows, so an agent gets its answer in time. Searches the run retries at the end get a new budget.
maxRequestRetriesRetries for a page that is refused (403, 429, a bot check), drops the connection or does not answer within 12 s; each retry comes from a fresh IP, within the time per query. 404s are not retried.
maxConcurrencyHow many queries run in parallel. The pages of each query are always fetched in parallel.
proxyConfigurationOff by default: pages load from the Actor's own IP, and a refused page is retried through the platform's datacenter proxy automatically. Turn it on to send every page through datacenter proxy or your own proxy URLs. Residential is not used for pages.
debugModeLog every search and page request (route, HTTP status, time, error) in the run log, for troubleshooting a site that will not load.
API
Bytewells speaks the Apify API. Existing integrations keep working: point apify-client at https://bytewells.com/api and use your Bytewells API token (Console → Settings → API access). The Actor ID is amethyst/rag-web-browser (or amethyst~rag-web-browser in URLs).
JavaScript · apify-client
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({
token: process.env.BYTEWELLS_TOKEN,
baseUrl: 'https://bytewells.com/api',
});
const input = {
"query": "what is retrieval augmented generation",
"maxResults": 3,
"replaceFailedPages": true,
"outputFormats": [
"markdown"
],
"htmlTransformer": "readableText",
"maxCharsPerPage": 0,
"removeElementsCssSelector": "nav, footer, script, style, noscript, svg, img[src^='data:'],\n[role=\"alert\"],\n[role=\"banner\"],\n[role=\"dialog\"],\n[role=\"alertdialog\"],\n[role=\"region\"][aria-label*=\"skip\" i],\n[aria-modal=\"true\"]",
"maxItems": 1000,
"requestTimeoutSecs": 40,
"maxRequestRetries": 1,
"maxConcurrency": 5,
"proxyConfiguration": {
"useApifyProxy": false
},
"debugMode": false
};
const run = await client.actor('amethyst/rag-web-browser').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);Python · apify-client
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["BYTEWELLS_TOKEN"], api_url="https://bytewells.com/api")
run_input = {
"query": "what is retrieval augmented generation",
"maxResults": 3,
"replaceFailedPages": True,
"outputFormats": [
"markdown"
],
"htmlTransformer": "readableText",
"maxCharsPerPage": 0,
"removeElementsCssSelector": "nav, footer, script, style, noscript, svg, img[src^='data:'],\n[role=\"alert\"],\n[role=\"banner\"],\n[role=\"dialog\"],\n[role=\"alertdialog\"],\n[role=\"region\"][aria-label*=\"skip\" i],\n[aria-modal=\"true\"]",
"maxItems": 1000,
"requestTimeoutSecs": 40,
"maxRequestRetries": 1,
"maxConcurrency": 5,
"proxyConfiguration": {
"useApifyProxy": False
},
"debugMode": False
}
run = client.actor("amethyst/rag-web-browser").call(run_input=run_input)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)HTTP · curl
curl -X POST "https://bytewells.com/api/v2/acts/amethyst~rag-web-browser/runs" \
-H "Authorization: Bearer $BYTEWELLS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"what is retrieval augmented generation","maxResults":3,"replaceFailedPages":true,"outputFormats":["markdown"],"htmlTransformer":"readableText","maxCharsPerPage":0,"removeElementsCssSelector":"nav, footer, script, style, noscript, svg, img[src^='\''data:'\''],\n[role=\"alert\"],\n[role=\"banner\"],\n[role=\"dialog\"],\n[role=\"alertdialog\"],\n[role=\"region\"][aria-label*=\"skip\" i],\n[aria-modal=\"true\"]","maxItems":1000,"requestTimeoutSecs":40,"maxRequestRetries":1,"maxConcurrency":5,"proxyConfiguration":{"useApifyProxy":false},"debugMode":false}'Runs are billed as compute from your credit balance. Paid Actors need an active rental or trial; otherwise the API answers 402 rental-required.
Related
More Actors from the same publisher.

Website Content Crawler for LLMs & RAG
Eimantas V · @amethyst
Crawl any website to clean Markdown for RAG and LLMs: navigation and footers stripped, tokens counted, ready-to-embed chunks. No browser, no proxy needed.
AIDeveloper toolsSEO tools$19/mo7-day free trial
Google Search Results Scraper - SERP API
Eimantas V · @amethyst
Scrape Google search results by keyword: organic results with ranks, places, top stories, knowledge panel, related searches, News and Videos. Any country.
SEO toolsMarketingLead generation$19/mo7-day free trial
Facebook Ads Library Scraper - Meta Ads, All Countries
Eimantas V · @amethyst
Scrape the Facebook Ads Library in any country: ad copy, images, videos, landing pages, CTAs, run dates and advertiser Pages. No login, no token needed.
MarketingSocial mediaBusiness$29/mo7-day free trial
Facebook Pages Scraper - Emails, Phones & Followers
Eimantas V · @amethyst
Scrape Facebook Pages by link, username or ID: email, phone, website, address, exact followers, category, rating and social links. No login or cookies.
Lead generationSocial mediaMarketing$19/mo7-day free trial
Facebook Posts Scraper - Pages, Profiles & Reactions
Eimantas V · @amethyst
Scrape posts from public Facebook Pages and profiles: text, date, reactions by type, comments, shares, video views and media. Date filters and new-post alerts.
Social mediaMarketingLead generation$19/mo7-day free trial
Google Maps Scraper - Business Leads & Emails
Eimantas V · @amethyst
Scrape Google Maps places by keyword and city: name, address, phone, website, rating, reviews, hours and coordinates, plus emails and socials from websites.
Lead generationTravelBusiness$19/mo7-day free trial