# Google Images Scraper: Image URLs, Thumbnails, Sources (`quarra/google-images-scraper`) Actor

Search Google Images by keyword, country and language. Get the image URL, thumbnail, title, source page, domain and position of every result, with Google's own filters (size, type, color, format, license, date). Many searches per run.

- **URL**: https://apify.com/quarra/google-images-scraper.md
- **Developed by:** [Quarra Labs](https://apify.com/quarra) (community)
- **Categories:** SEO tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.80 / 1,000 images

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Images Scraper: image URLs, thumbnails, titles and source pages

Search Google Images by keyword, country and language, and get one row per image: the **image URL**, the **thumbnail**, the **title**, the **page it appears on**, the **domain** and the **position** in Google's results. Run as many searches as you like in one go, apply Google's own filters (size, type, color, format, license, date), and set a hard limit on images per search and in total.

No browser to maintain and nothing to configure: you give search terms, you get images.

### What you get

For every image:

| Field | What it is |
|---|---|
| `query`, `queryIndex` | The search term and its position in your list (0-based) |
| `position` | Rank of the image in Google's results for this search (starts at 1) |
| `imageUrl`, `directImage` | Address of the full image on its original site. `directImage` is `false` for Instagram and Facebook posts, where Google gives an address that opens the post page rather than the file |
| `thumbnailUrl` | Google's small cached copy |
| `title`, `alt` | Title Google shows; alternative text when it differs |
| `sourceName` | Name of the site that hosts the page (the domain instead, when the site name is a person's name) |
| `pageUrl`, `domain` | Page where the image appears, and its domain (no `www.`) |
| `imageDomain`, `format` | Domain serving the file; jpg, png, gif, webp, svg... read from the address (null when it does not say) |
| `country`, `language`, `scrapedAt` | What was asked, and when |

Each run also writes an `OUTPUT` record with, for every search (the first 200), the number of images delivered, Google's **related searches** and spelling suggestion, and why the run stopped.

#### Example row

```json
{
  "type": "image",
  "status": "ok",
  "query": "mountain lake",
  "queryIndex": 0,
  "position": 2,
  "imageUrl": "https://www.nps.gov/im/nccn/images/NOCA_MOLA_LowerEast.jpg",
  "thumbnailUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSy0XJ24ERC3ss3x6OOSMkahXIysmwpQnmZyPBmImkw5w&s=10",
  "title": "Mountain Lakes Monitoring (U.S. National Park Service)",
  "alt": null,
  "sourceName": "National Park Service",
  "pageUrl": "https://www.nps.gov/im/nccn/mountain-lakes.htm",
  "domain": "nps.gov",
  "imageDomain": "nps.gov",
  "format": "jpg",
  "directImage": true,
  "country": "US",
  "language": "en",
  "scrapedAt": "2026-10-22T05:21:14.000Z"
}
```

### Input

| Field | Meaning |
|---|---|
| `queries` | Search terms, one per line, up to 5,000. A Google Images link is read as its search term. Operators such as `site:` and `filetype:` work (see Pricing). |
| `maxResultsPerQuery` | Images per search, 1 to 200 (default 100). Google serves about 100 per search page and at most 200 per term. |
| `maxItems` | Stop after this many images in total (optional). |
| `countryCode`, `languageCode` | Where and in which language the search is made (`US`/`en` by default). Codes or names. |
| `imageSize`, `minResolution` | Large, medium, icon; or "at least 400 x 300 ... 70 MP" |
| `imageType` | Photo, clip art, line drawing, animated (GIF), face |
| `color` | Full color, black and white, transparent, or one color |
| `fileType` | jpg, png, gif, webp, svg, bmp, avif, ico, raw |
| `aspectRatio` | Tall, square, wide, panoramic |
| `usageRights` | Creative Commons licenses, or commercial and other licenses |
| `uploadedWithin` | Past 24 hours, week, month, year |
| `safeSearch` | Turn Google SafeSearch on |

```json
{
  "queries": ["mountain lake", "alpine cabin"],
  "maxResultsPerQuery": 100,
  "countryCode": "US",
  "languageCode": "en",
  "imageType": "photo",
  "minResolution": "4mp"
}
```

Google returns different images for each filter combination, so repeating a search with another filter is the way to collect more than 200 images for one subject.

### Pricing

Pay per event: a small fee per run, a fee per search Google answers, and a price per image delivered. Nothing else is charged: no fee for duplicates, none for error rows.

| Event | Free and Bronze | Silver | Gold and above |
|---|---|---|---|
| Run start | $0.005 | $0.005 | $0.005 |
| Search | $0.003 | $0.003 | $0.003 |
| Image delivered | $0.0030 | $0.0029 | $0.0028 |

- **Search**: charged once per search term that Google answers, even when it has no image. A search with an operator such as `site:`, `filetype:`, `intitle:`, `inurl:` or `related:` is charged as 5 searches, which is what it costs to run; quotes, `-word`, `before:` and `imagesize:` are charged as one. Each search is charged at most once per run.
- **Image**: $3.00 per 1,000 images on the base plan, $2.90 on Silver and $2.80 on Gold.
- The run start is charged once per run; the platform may scale it with memory (this Actor runs on 256 MB).

Example: 50 images from one search cost $0.158 on the base plan. 5,000 images (50 searches of 100) cost $15.155.

Your **maximum charge per run** is never exceeded: a search starts only when it and at least one image fit in what is left, and the run stops when the next image would exceed it, and says so.

### Limits, said plainly

- **Up to 200 images per search term.** That is the most Google lists for one search. Use filters or related terms for more.
- **No pixel size per image.** Google's result list does not carry width and height, so the fields are not there rather than guessed. Use `minResolution` to guarantee a minimum.
- **Not the full web.** Positions are what Google shows to a visitor from the chosen country at the time of the run; they change over time and between runs.
- **Image rights belong to their owners.** The Actor collects links and metadata; check each image's license before reusing it.
- **Duplicates are removed per search** (same image address). A search that returns fewer images than asked delivers and charges only those images, plus the search.
- The first results of a new search term can take a few seconds; a run of 50 searches takes about a minute.

### FAQ

**Is anything different on Apify's free plan?**
Available on paid Apify plans only, except for the prefilled example (the search "mountain lake", 20 images, US, English, no filter), which returns stored sample rows from the day the Actor was built, free of charge, on any plan. Any other input on a free plan returns a notice and charges nothing but the run start. Reason: Apify does not pay developers for runs on free plans, and each search has a real cost.

**What happens if a search finds nothing?**
You get a free `error` row with the reason and the other searches carry on; the run does not fail because one search is empty. `no_results` (Google answered with no image) and `search_failed` (Google could not run it, for example `site:` with a site it does not know) are charged as a search, since Google was asked; no image is charged. A search term refused before searching (`invalid_query`) or a search the service could not answer (`no_answer`, `rejected_query`) is not charged at all, unless Google answered an earlier try of that search: then it is charged once as a search, never for images.

**What if I stop or restart the run?**
Images already delivered are kept and are not charged again, and a search already made is not made or charged again. A run moved to another server resumes where it stopped. A run that had finished does nothing more if you resurrect it.

**Can I search in another country or language?**
Yes: `countryCode` and `languageCode` accept codes (`FR`, `fr`, `pt-BR`) or names. Results are those a visitor from that country sees.

**Does the Actor send anything to Quarra?**
Only when a run fails, runs out of time, or stops early because the image service is unavailable: the Actor name and build, the type of error, the line of our code where it happened, and the memory and time limit of the run. Never your input, your results, the error text or your account.

**Is it legal to collect this data?**
The Actor reads the public result list of Google Images and does not log in. Check the terms of the sites you reuse images from, and the license of every image you publish.

### Support

Open an issue in the Issues tab: we reply within 48 hours and tell you what was fixed and in which version. — Sam, Quarra

# Actor input Schema

## `queries` (type: `array`):

What to search for in Google Images, as a user would type it. One search per line, up to 5,000. A Google Images link is read as its search term. Operators such as site: and filetype: work; a search with one of them is charged as 5 searches. Available on paid Apify plans only. The prefilled example also runs on the free plan, from stored results.

## `maxResultsPerQuery` (type: `integer`):

How many images to collect for each search term. Google serves about 100 per search page and at most 200 per term; to go further, repeat the term with different filters.

## `maxItems` (type: `integer`):

Stops the run once this many images are delivered, across all searches. Leave empty for no limit.

## `countryCode` (type: `string`):

Two-letter country code (US, GB, FR, DE, CA, AU, IN...) or the country name. Results are those a user in that country sees.

## `languageCode` (type: `string`):

Language code (en, fr, de, es, pt-BR, zh-CN, ja...) or the language name.

## `imageSize` (type: `string`):

Google's size filter. Cannot be combined with Minimum resolution.

## `minResolution` (type: `string`):

Only images at least this large (Google's "larger than" filter).

## `imageType` (type: `string`):

Google's type filter.

## `color` (type: `string`):

Google's color filter: a color mode or one color.

## `fileType` (type: `string`):

Only images in this format.

## `aspectRatio` (type: `string`):

Google's shape filter.

## `usageRights` (type: `string`):

Google's license filter. Check each image's license on its page before reuse.

## `uploadedWithin` (type: `string`):

Only images Google dates within this period.

## `safeSearch` (type: `boolean`):

Turn Google SafeSearch on to filter explicit images.

## Actor input object example

```json
{
  "queries": [
    "mountain lake"
  ],
  "maxResultsPerQuery": 20,
  "countryCode": "US",
  "languageCode": "en",
  "imageSize": "any",
  "minResolution": "any",
  "imageType": "any",
  "color": "any",
  "fileType": "any",
  "aspectRatio": "any",
  "usageRights": "any",
  "uploadedWithin": "any",
  "safeSearch": false
}
```

# Actor output Schema

## `results` (type: `string`):

Every image with its address, thumbnail, title, source page and rank, and free rows with the reason when a search returned nothing.

## `gallery` (type: `string`):

One line per image with the thumbnail, title and links.

## `summary` (type: `string`):

Counts, related searches per search, why the run stopped.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "mountain lake"
    ],
    "maxResultsPerQuery": 20,
    "countryCode": "US",
    "languageCode": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("quarra/google-images-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": ["mountain lake"],
    "maxResultsPerQuery": 20,
    "countryCode": "US",
    "languageCode": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("quarra/google-images-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "mountain lake"
  ],
  "maxResultsPerQuery": 20,
  "countryCode": "US",
  "languageCode": "en"
}' |
apify call quarra/google-images-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,quarra/google-images-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/cC06pYqs1XVlP3PXH/builds/ohhRNoTTP2ud8swm5/openapi.json
