# Google Lens Scraper (`scrapers-hub/google-lens-scraper`) Actor

Google Lens Scraper runs reverse image search on any image URL and returns visual matches, extracted text and result counts across search types. 🔎 Use it for product matching, counterfeit detection, OCR and visual competitor research.

- **URL**: https://apify.com/scrapers-hub/google-lens-scraper.md
- **Developed by:** [Scrapers Hub](https://apify.com/scrapers-hub) (community)
- **Categories:** AI, E-commerce, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 🔎 Google Lens Scraper – Reverse Image Search, Visual Match & OCR Extraction

The **Google Lens Scraper** runs your images through Google Lens and returns the reverse image search results as structured JSON — matching page URLs, their titles, and the visible text Google reads off the image. Point it at one or more public image URLs and it opens a real browser session on a residential proxy, submits the image to Google Lens, and parses the response into dataset records you can query, join and store.

Reverse image search is one of the few data sources that lets you start from a picture rather than a keyword. That makes this Google Lens scraper useful for brand protection teams tracking where a product photo has been republished, e-commerce researchers finding which retailers list a given item, journalists verifying where an image first appeared, and anyone who needs OCR text pulled out of screenshots and photographs at scale.

***

### 📊 What Data Can You Extract with This Google Lens Scraper?

Every dataset item records which Lens view produced it and which source image it came from. The fields below are everything the actor writes.

| Category | Fields | What it gives you |
|---|---|---|
| 🧭 Record type | `view` | Which Lens view the record represents — the requested search type, `ocr`, or `globalErrors` for images that could not be processed |
| 🖼️ Source image | `imageUrl` | The public image URL you submitted, so results always trace back to their input |
| 🔗 Match results | `results` | The array of matches found for the image, each entry carrying `href` and `title` |
| 🔢 Result volume | `resultsCount` | How many matches were parsed for that image and view |
| 📝 Text extraction | `text` | The visible text read from the Lens page for the image, returned on `ocr` records |
| ⚠️ Failure detail | `error` | The reason an image could not be processed, on records where `view` is `globalErrors` |

The field that does the most work is `results`. Each entry is a `{ "href": ..., "title": ... }` pair pointing at a page where the image — or something visually close to it — was found. Deduplicating `href` values across a batch of product photos is often the fastest way to build a list of sites republishing your imagery.

***

### 🌟 Key Features of the Google Lens Scraper

| Feature | Description |
|---|---|
| 🖼️ Batch image processing | Submit many image URLs in one run; each is processed in turn and tagged with its `imageUrl` in the output |
| 🔁 Automatic retry on blocks | `maxRetriesPerImage` opens a fresh browser session on a new residential proxy IP each time Google throws a CAPTCHA or JS challenge |
| 🌐 Configurable residential proxy | `proxyConfiguration` is fully user-configurable and defaults to Apify's `RESIDENTIAL` group, which is what Google Lens realistically requires |
| 🗂️ Multiple search views | `searchTypes` accepts `all`, `exact-match`, `visual-match` and `ocr`, and one run can emit records for several views at once |
| 📝 Built-in OCR view | Requesting `ocr` returns the visible text read from the image in the `text` field, no separate OCR service needed |
| 🌍 Language control | The `language` field sets the Lens result locale (`en`, `fr`, `bn` and so on) so you can compare results across markets |
| 🐛 Debug HTML capture | With `saveDebugHtmlOnFailure` on, blocked or empty-parse pages are saved to the key-value store for inspection |
| 🧾 Errors kept in the dataset | Images that fail after all retries are written as `globalErrors` records with an `error` message rather than silently dropped |
| 🎭 Real browser rendering | The scraper drives an actual browser rather than issuing bare HTTP requests, which is necessary for Lens to respond at all |

***

### 🚀 Why Choose This Google Lens Scraper?

**Purpose-built for Google's anti-automation defences.** Google aggressively challenges automated traffic on Search and Lens. This actor treats that as the normal case rather than an exception: each retry gets a brand new browser session on a fresh residential IP, and the retry budget is yours to set through `maxRetriesPerImage`.

**Every result traces back to its source image.** Because `imageUrl` is written on every record — including error records — you can submit a hundred images in a single run and still reconcile every row back to the exact input that produced it. No positional matching, no guesswork.

**OCR and reverse image search from one submission.** Including `ocr` in `searchTypes` alongside a match view means one Lens session produces both the visible text and the matching pages. That halves the work when you are processing screenshots, product packaging or documents.

**Transparent failure handling.** Blocked images become `globalErrors` records with a readable `error` string, and the raw page HTML is preserved in the key-value store when `saveDebugHtmlOnFailure` is enabled. When something goes wrong you get evidence, not an empty dataset.

***

### 📥 Input

```json
{
  "searchTypes": ["all"],
  "imageUrls": [
    { "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png/200px-Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png" }
  ],
  "language": "en",
  "maxRetriesPerImage": 5,
  "saveDebugHtmlOnFailure": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

#### 🔧 Google Lens Scraper Input Fields

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `searchTypes` | array | ✅ Yes | `["all"]` | Which Google Lens result types to extract. Implemented values are `all`, `exact-match`, `visual-match` and `ocr`. `translate-ocr`, `ai-mode`, `products` and `homework` are not implemented yet in this version |
| `imageUrls` | array | ✅ Yes | prefilled example image | Public URLs of images to run through Google Lens |
| `language` | string | No | `"en"` | Language for Google Lens results (e.g. `en`, `fr`, `bn`) |
| `maxRetriesPerImage` | integer | No | `5` | Google frequently blocks automated requests with a CAPTCHA/JS challenge. Each retry opens a fresh browser session on a new residential proxy IP |
| `saveDebugHtmlOnFailure` | boolean | No | `true` | When a run gets blocked or the parser finds nothing, save the raw page HTML to the key-value store so it can be inspected and used to improve the parser |
| `proxyConfiguration` | object | No | `{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}` | Google aggressively blocks datacenter IPs for Search/Lens. Residential proxy is effectively required |

#### 💡 Input Examples

**Reverse image search on a single product photo**

```json
{
  "searchTypes": ["all"],
  "imageUrls": [{ "url": "https://cdn.example.com/products/chair-front.jpg" }],
  "language": "en"
}
```

**OCR only — pull text out of screenshots**

```json
{
  "searchTypes": ["ocr"],
  "imageUrls": [
    { "url": "https://cdn.example.com/screenshots/invoice-01.png" },
    { "url": "https://cdn.example.com/screenshots/invoice-02.png" }
  ]
}
```

**Batch run with a higher retry budget and a French locale**

```json
{
  "searchTypes": ["visual-match", "ocr"],
  "imageUrls": [
    { "url": "https://cdn.example.com/img/a.jpg" },
    { "url": "https://cdn.example.com/img/b.jpg" },
    { "url": "https://cdn.example.com/img/c.jpg" }
  ],
  "language": "fr",
  "maxRetriesPerImage": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

***

### 📤 Output

A match record produced for a requested search view:

```json
{
  "view": "all",
  "imageUrl": "https://cdn.example.com/products/chair-front.jpg",
  "resultsCount": 2,
  "results": [
    {
      "href": "https://shop.example.org/living-room/lounge-chair",
      "title": "Lounge Chair – Oak and Wool"
    },
    {
      "href": "https://blog.example.net/2024/interiors-roundup",
      "title": "Twelve chairs worth the money"
    }
  ]
}
```

An OCR record for the same image:

```json
{
  "view": "ocr",
  "imageUrl": "https://cdn.example.com/products/chair-front.jpg",
  "text": "LOUNGE CHAIR  OAK / WOOL  MADE IN PORTUGAL"
}
```

An error record when an image could not be processed:

```json
{
  "view": "globalErrors",
  "imageUrl": "https://cdn.example.com/products/broken.jpg",
  "error": "Blocked by Google after all retries"
}
```

#### 🧾 Google Lens Output Fields

| Field | Type | Description |
|---|---|---|
| `view` | string | The Lens view this record belongs to — the requested search type, `ocr`, or `globalErrors` |
| `imageUrl` | string | The source image URL this record was produced from |
| `results` | array | Matches parsed from the Lens response; each entry has `href` and `title` |
| `resultsCount` | integer | Number of matches in `results` |
| `text` | string | Visible text extracted from the page for the image, present on `ocr` records |
| `error` | string | Error message, present when the image failed to process |

Note that `resultsCount` and `results` appear on match records, `text` appears on `ocr` records, and `error` appears on `globalErrors` records. Filter on `view` before reading the rest of the row.

***

### 💻 How to Use the Google Lens Scraper (Step by Step)

#### Step 1: Prepare publicly reachable image URLs

The Google Lens scraper submits image URLs to Lens, so every image must be fetchable from the public internet without a login, signed URL or IP allowlist. Images sitting behind a private CDN rule, an S3 bucket policy or a corporate VPN will not work. If your source images are private, upload copies to a public bucket or use Apify's key-value store to host them before the run.

#### Step 2: Choose your search types

`searchTypes` is required and defaults to `["all"]`. Use `all` when you want the broadest set of matches, `exact-match` or `visual-match` when you want to think in terms of Lens's own result tabs, and `ocr` when you want the text read off the image. You can request several at once — each requested view produces its own dataset record per image, all sharing the same `imageUrl`.

#### Step 3: Set the language

The `language` field controls the locale Lens responds in and defaults to `en`. If you are researching a specific market, set it to that market's code — `fr`, `de`, `es`, `bn` and so on. Running the same images at two different language settings and comparing the `results` arrays is a practical way to see how visibility differs by region.

#### Step 4: Configure the residential proxy

`proxyConfiguration` is the single most important setting for a successful run. It defaults to Apify Proxy with the `RESIDENTIAL` group, which is what Google Lens effectively requires. Datacenter IPs are challenged almost immediately. Unless you have a specific reason to change it, leave the default in place — and if you supply a custom configuration, make sure it resolves to residential exit nodes.

#### Step 5: Tune the retry budget

`maxRetriesPerImage` defaults to 5, and each retry opens a completely fresh browser session on a new proxy IP. For small, high-value batches it is worth raising this to 10 or more so that a temporary block does not cost you a result. For large exploratory batches, keep it lower so the run does not spend all its time fighting one stubborn image.

#### Step 6: Run and check the log

Start the run. The log prints a line per image as it is processed, and warns when the parser finds zero results. If `saveDebugHtmlOnFailure` is enabled, the raw HTML for those empty parses is written to the key-value store under a `debug-empty-parse-*` key — open it to see whether you were served a challenge page or a genuinely empty result set.

#### Step 7: Read the dataset by view

In the Dataset tab, filter or group by `view` first. Match records carry `resultsCount` and `results`; OCR records carry `text`; `globalErrors` records carry `error`. Export to JSON if you want the nested `results` array intact, or flatten to CSV if you only need one row per match URL.

***

### 🔌 API Access & Integrations

Run the Google Lens scraper over HTTP and get dataset items back in the same call:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers-hub~google-lens-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchTypes": ["all"],
    "imageUrls": [{ "url": "https://cdn.example.com/products/chair-front.jpg" }],
    "language": "en",
    "maxRetriesPerImage": 5,
    "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
  }'
```

With the Python client:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")

run = client.actor("scrapers-hub/google-lens-scraper").call(run_input={
    "searchTypes": ["all", "ocr"],
    "imageUrls": [
        {"url": "https://cdn.example.com/img/a.jpg"},
        {"url": "https://cdn.example.com/img/b.jpg"},
    ],
    "language": "en",
    "maxRetriesPerImage": 8,
    "proxyConfiguration": {"useApifyProxy": True, "apifyProxyGroups": ["RESIDENTIAL"]},
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item["view"] == "ocr":
        print(item["imageUrl"], "->", item.get("text"))
    elif item["view"] == "globalErrors":
        print("FAILED:", item["imageUrl"], item.get("error"))
    else:
        for match in item.get("results") or []:
            print(match["href"], match.get("title"))
```

Results can also be routed into Zapier, Make, Google Sheets or Slack, or delivered to your own service using an Apify webhook on run completion.

***

### 💡 Best Use Cases for Google Lens Data

#### 🛡️ Brand Protection and Image Theft Detection

Submit your own product photography and campaign creative, then review the `href` values in `results`. Any domain you do not recognise is a candidate for unlicensed reuse. Because each record carries `imageUrl`, you can run a full asset library through the Google Lens scraper and produce a per-asset infringement list rather than checking images one at a time.

#### 🛒 E-commerce Product Matching

Retailers and marketplaces often list the same item using the manufacturer's press photo. Reverse image searching that photo surfaces the competing listings in `results`, complete with page `title`, which is usually enough to identify the retailer and product name without visiting each page. It is a fast route to a price-comparison shortlist.

#### 📰 Image Provenance and Fact-Checking

Journalists and OSINT researchers use reverse image search to find where a photograph appeared previously. Sorting the `results` array by domain and cross-referencing publication dates helps establish whether an image is genuinely new or recycled from an earlier event. The `text` field from an `ocr` record adds any captions or watermarks burned into the picture.

#### 📄 Bulk OCR for Screenshots and Documents

Requesting the `ocr` view turns the actor into a batch text-extraction pipeline. Feed it screenshots, scanned notices, product packaging or signage photos and read the `text` field from each record. Because `imageUrl` is preserved, extracted text stays joined to its source file with no extra bookkeeping.

#### 🎨 Visual Content Discovery and Trend Research

Designers and content teams can submit a reference image and use `results` to find visually similar pages across the web. The combination of `href` and `title` gives enough context to triage which matches are worth opening, and `resultsCount` gives a rough signal for how visually distinctive an image is.

#### 🌍 Cross-Market Visibility Comparison

Run the same image set twice with different `language` values and compare the `results` arrays. Divergence between locales tells you which markets already surface your imagery and which do not — useful input for localisation and international SEO planning.

#### 🔍 Duplicate Asset Auditing in Large Libraries

Media teams sitting on tens of thousands of assets can use reverse image search to find where their own images already live online, including on their own subdomains and partner sites. Deduplicating `href` across a batch produces a distribution map of an asset library that no internal DAM report can give you.

***

### ⚙️ Tips for Better Google Lens Scraping Results

- **Keep the residential proxy default.** Google Lens challenges datacenter IPs almost immediately. If you override `proxyConfiguration`, make sure the replacement is residential, or expect most images to end up as `globalErrors`.
- **Raise `maxRetriesPerImage` for small, important batches.** Each retry is a fresh session on a fresh IP, so a higher budget genuinely improves the hit rate when you only have a handful of images that matter.
- **Verify image URLs are public before running.** A signed or expiring URL that works in your browser may already be dead by the time Lens fetches it. Test with an incognito window or a plain `curl`.
- **Leave `saveDebugHtmlOnFailure` enabled while you are tuning.** The saved HTML is the only reliable way to distinguish "Google blocked us" from "Lens genuinely returned nothing for this image".
- **Batch in moderate sizes.** Very large image lists in a single run take longer and give you less granular restart points. Several medium runs are usually easier to manage and re-run selectively.
- **Filter on `view` before parsing.** The three record shapes carry different fields. Reading `results` on an `ocr` record or `text` on a match record will simply give you nothing.

***

### 🛠️ Troubleshooting

**All my images came back as `globalErrors`.**
This is almost always a proxy problem. Confirm `proxyConfiguration` uses Apify Proxy with the `RESIDENTIAL` group. Datacenter and free proxies are blocked by Google Search and Lens very quickly. Raising `maxRetriesPerImage` helps at the margin, but it cannot compensate for the wrong IP type.

**The run finished but `results` is empty and `resultsCount` is 0.**
Either Lens genuinely found no matches for that image, or the page returned was a challenge rather than a result set. With `saveDebugHtmlOnFailure` on, open the `debug-empty-parse-*` entry in the key-value store — a CAPTCHA page is immediately recognisable and means you should retry with a higher retry budget.

**I asked for `products` or `ai-mode` and got nothing.**
Those views, along with `translate-ocr` and `homework`, are not implemented in this version. Only `all`, `exact-match`, `visual-match` and `ocr` produce records; unrecognised values are dropped and the run falls back to `all`.

**The `text` field is empty on my OCR records.**
The OCR view returns the visible text from the Lens page for that image. Low-resolution images, heavily stylised type, or photographs with no legible text will produce little or nothing. Try a higher-resolution version of the same image.

**Nothing ran and the log says no image URLs were provided.**
`imageUrls` expects a list of objects with a `url` key, matching the request-list format shown in the input examples. A plain array of bare strings will not be picked up.

***

### ❓ Frequently Asked Questions About Google Lens Scraping

**What does the Google Lens Scraper do?**
It submits public image URLs to Google Lens through a real browser session and returns the reverse image search results — matching page URLs and titles in `results`, plus optional OCR text in `text` — as structured dataset records.

**Do I need a Google account or API key?**
No. The actor drives Google Lens through a browser session on a residential proxy. You only need your Apify token to start runs via the API.

**Can I search using an image file from my computer?**
Not directly. The input takes URLs, so the image must be hosted somewhere publicly reachable first. Uploading to a public bucket or Apify's key-value store and passing that URL is the usual workaround.

**Why is a residential proxy required for the Google Lens scraper?**
Google aggressively blocks datacenter IP ranges on Search and Lens with CAPTCHA and JavaScript challenges. Residential exit nodes look like ordinary consumer traffic, which is why the default `proxyConfiguration` uses the `RESIDENTIAL` group.

**How many images can I process in one run?**
There is no fixed cap in the input schema — `imageUrls` is a list and each entry is processed in turn. Practical batch size depends on how long you want the run to take and how much retry budget you have allocated per image.

**What is the difference between `exact-match` and `visual-match`?**
They correspond to different Google Lens result views: exact matches of the same image versus visually similar imagery. Both are written as records with the same field shape, distinguished by the `view` value.

**Can the Google Lens scraper extract text from images?**
Yes. Include `ocr` in `searchTypes` and each image produces a record with `view` set to `ocr` and the extracted text in the `text` field.

**Does it work in languages other than English?**
Yes. Set `language` to the locale code you want, such as `fr` or `bn`. This changes the locale Lens responds in, which can change both the results and their titles.

**What happens to images that fail?**
They are written to the dataset as records with `view` set to `globalErrors`, carrying the source `imageUrl` and a human-readable `error` message. Nothing is silently dropped.

**How do I debug an empty result set?**
Keep `saveDebugHtmlOnFailure` at its default of `true`. The raw HTML of the page that produced zero results is saved to the run's key-value store, so you can inspect whether you were served a challenge or a genuine no-match page.

**Can I get the price or seller of a matched product?**
Not in this version. The parser returns `href` and `title` for each match. If you need commercial detail, use the returned URLs as input to a scraper for that specific site.

**Is the output the same for every search type?**
Match views (`all`, `exact-match`, `visual-match`) produce `resultsCount` and `results`. The `ocr` view produces `text`. Error records produce `error`. Always branch on `view` when parsing.

**Can I schedule recurring reverse image searches?**
Yes. Save the input and use Apify's Scheduler to re-run it on a cadence — a common pattern for brand protection, where you want to know when new sites start hosting your imagery.

**How do I export the Google Lens results?**
Use the dataset export options in the Apify Console (JSON, CSV, Excel, XML) or call `run-sync-get-dataset-items` to receive the items directly in the API response. JSON is recommended because `results` is a nested array.

**Does this scraper collect anything beyond what Google Lens shows?**
No. It returns what the Lens response contains for the images you submit — matching page URLs, their titles, and the visible text on the page. It does not access any private or authenticated source.

***

### 🆘 Support & Feedback

Hit a bug, an unhandled edge case, or a parsing gap? Open a ticket in the **Issues** tab on the actor page, and include the image URL and run ID so the problem can be reproduced quickly.

Need a customised build — additional Lens views, a different output shape, or integration with your own asset pipeline? Email **scraperhubapi@gmail.com** with the details.

If the Google Lens scraper is useful to you, a rating and a short review on the actor page genuinely helps and guides what gets improved next.

***

### ⚖️ Disclaimer

This Google Lens scraper retrieves only publicly available reverse image search results for images you supply. It does not bypass authentication, access private galleries, or retrieve anything a normal Google Lens user could not see.

You are responsible for how you use this actor and the data it produces. That includes having the right to submit the images you process, complying with Google's terms of service, and complying with the terms of any site you subsequently visit or scrape based on the returned URLs.

Where images or extracted text contain personal data — faces, names, addresses or other identifiers — you act as the data controller for whatever you store, and you must handle it in accordance with GDPR, CCPA and any other privacy regulation applicable to you. Reverse image search on photographs of identifiable individuals carries particular privacy risk; make sure you have a lawful basis before doing it.

If you believe data collected through this actor should be removed, contact **scraperhubapi@gmail.com** with the details and the request will be addressed.

# Actor input Schema

## `searchTypes` (type: `array`):

Which Google Lens result types to extract. 'translate-ocr', 'ai-mode', 'products' and 'homework' are not implemented yet in this version.

## `imageUrls` (type: `array`):

Public URLs of images to run through Google Lens.

## `language` (type: `string`):

Language for Google Lens results (e.g. en, fr, bn).

## `maxRetriesPerImage` (type: `integer`):

Google frequently blocks automated requests with a CAPTCHA/JS challenge. Each retry opens a fresh browser session on a new residential proxy IP.

## `saveDebugHtmlOnFailure` (type: `boolean`):

When a run gets blocked or the parser finds nothing, save the raw page HTML to the key-value store so it can be inspected and used to improve the parser.

## `proxyConfiguration` (type: `object`):

Google aggressively blocks datacenter IPs for Search/Lens. Residential proxy is effectively required.

## Actor input object example

```json
{
  "searchTypes": [
    "all"
  ],
  "imageUrls": [
    {
      "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png/200px-Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png"
    }
  ],
  "language": "en",
  "maxRetriesPerImage": 5,
  "saveDebugHtmlOnFailure": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Records scraped by Google Lens Scraper, stored in the run's default dataset.

# 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 = {
    "imageUrls": [
        {
            "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png/200px-Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers-hub/google-lens-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 = {
    "imageUrls": [{ "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png/200px-Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png" }],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapers-hub/google-lens-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 '{
  "imageUrls": [
    {
      "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png/200px-Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call scrapers-hub/google-lens-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapers-hub/google-lens-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/lsqzUbu0WTxwsUD6x/builds/ybAlQr17nTBl1bRI1/openapi.json
