gemini-scraper
v0.1.0
Published
Gemini scraper and Gemini API endpoint client built on ScrapingBee. Send prompts to Google Gemini, get text, markdown and citations as JSON.
Maintainers
Readme
gemini-scraper
Node client for ScrapingBee's Gemini scraper API. One call sends a prompt to Google Gemini and hands back the answer as text and markdown, with citations attached when Gemini provides them. Zero dependencies, Node 18+.
Checked against the live endpoint on 2026-08-25. GET /api/v1/gemini, 15 credits a call.
npm install gemini-scraperKey from app.scrapingbee.com, 1,000 credits free to start.
Ask something
const { GeminiScraper } = require("gemini-scraper");
const scraper = new GeminiScraper(process.env.SCRAPINGBEE_API_KEY);
const answer = await scraper.ask("Best programming languages for data science");
console.log(answer.markdown);
console.log(answer.cost, answer.requestId);Reading the answer
GeminiResponse wraps the five fields the endpoint actually returns:
answer.text // results_text, plain prose
answer.markdown // results_markdown, formatting intact
answer.citations // citations, an array that is often empty
answer.html // full_html, the rendered answer pane
answer.prompt // prompt, echoed backDo not assume citations arrive. Plenty of prompts come back with an empty array, so branch on
answer.citations.length rather than indexing into it.
Why country matters
Gemini localises. Ask about pricing, vendors or anything regulated and the answer shifts by market, so a single run tells you very little:
for (const geo of ["us", "gb", "de"]) {
const a = await scraper.ask("best invoicing software for freelancers", { country_code: geo });
console.log(geo, a.citations.length, a.text.slice(0, 100));
}Sweeping a prompt list
askMany walks the list in order and drops a null where a prompt failed, so one bad call does
not cost you the run:
const prompts = [
"best web scraping api",
"how to scrape a javascript heavy site",
"cheapest way to collect serp data",
];
const answers = await scraper.askMany(prompts, { country_code: "us" });
answers.forEach((a, i) => console.log(prompts[i], "->", a ? a.text.slice(0, 80) : "FAILED"));Budget before you loop. 15 credits a prompt means a 200-prompt sweep costs 3,000:
console.log(await scraper.usage());That call is free, and rate limited to 6 per minute.
Labelling runs
Pass tag to stamp your own identifier onto a request, which is how you tell two scheduled jobs
apart when they share one key:
await scraper.ask("best crm for small teams", { tag: "weekly-visibility" });When it fails
GeminiScraperError carries statusCode, body and requestId. A 500 is never charged, so
retrying is free:
const { GeminiScraperError } = require("gemini-scraper");
try {
await scraper.ask("...");
} catch (error) {
if (error instanceof GeminiScraperError) console.error(error.statusCode, error.requestId);
}Cost
| Call | Credits |
| --- | --- |
| One prompt | 15 |
| usage() | 0 |
| HTTP 500 | 0 |
Tiers at scrapingbee.com/pricing.
Neighbouring endpoints
Same key, same billing: ChatGPT . Google AI Mode . Google search . Google News . Perplexity
Notes
Public content only. Scraping behind a login is prohibited by the ScrapingBee terms. Do not paste your API key into AI coding assistants.
Gemini docs . all endpoints . repo
MIT.
