# Drogasil Product Prices Scraper (`automation-lab/drogasil-pharmacy-products-prices`) Actor

Search Drogasil Brazil and export product SKUs, brands, categories, BRL prices, discounts and stock signals for recurring pharmacy retail snapshots.

- **URL**: https://apify.com/automation-lab/drogasil-pharmacy-products-prices.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 60.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.37 / 1,000 item extracteds

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

## Drogasil Product Prices Scraper

Collect **Drogasil product prices** for Brazilian pharmacy retail analysis. Search the public Drogasil storefront and export one snapshot per unique SKU, including product identity, brand, categories, current and list prices in BRL, discounts and stock signals.

Use it for scheduled assortment research, spreadsheet comparisons and recurring pharmacy price snapshots. This Actor collects anonymous public catalogue data, not patient records, account details, loyalty offers or personalized prices.

### Who is this for?

- Retail analysts comparing pharmacy product assortments and public selling prices.
- Brand teams checking how their products appear in Drogasil search.
- Data engineers adding dated Brazilian retail snapshots to a warehouse.

### Why use this Actor?

Get typed price records instead of HTML pages. Product identity and batched live pricing come from the storefront's structured data, avoiding a separate product-page download for every SKU. Global deduplication prevents charging twice for the same SKU within a run, even across overlapping searches.

No browser, login or proxy setup is required. The Actor makes sequential requests with a stable request session and conservative pacing, and switches automatically to Apify Proxy (datacenter, then Brazilian residential) if Drogasil blocks the direct connection. If Drogasil blocks a request or changes its response structure, the run fails rather than silently claiming a complete empty catalogue.

### Getting started

1. Open the Input tab.
2. Enter product names, ingredients or brands in **Product searches**.
3. Set **Maximum unique products** to bound the total run output.
4. Start the Actor and wait for completion.
5. Open the Dataset tab and export JSON, CSV or Excel.

```json
{
  "searchQueries": ["paracetamol"],
  "maxItems": 20
}
```

### Input parameters

| Field | Default | Meaning |
| --- | --- | --- |
| `searchQueries` | `["paracetamol"]` | 1–10 nonblank strings, each at most 150 characters. Trimmed and processed in order. |
| `maxItems` | `20` | Global limit of 1–1000 unique product snapshots after deduplication. Zero/unlimited is unsupported. |

Drogasil controls relevance, synonyms, sponsored products and ranking. A search is **not an exact phrase filter**, and a returned product need not contain every search word in its title. Queries are not combined with AND/OR logic. Duplicate trimmed queries are removed; differently cased queries remain separate source searches.

The first query yielding a SKU is retained on its row. When an earlier query fills the global limit, later queries are not visited. There are no explicit-URL, category, brand-filter, postcode or logged-in modes. Unsupported input fields are rejected.

### Extracted data

| Field | Meaning |
| --- | --- |
| `sku` | Stable source SKU, returned as text. |
| `name`, `brand` | Product identity; brand can be null. |
| `categories` | Source category names. |
| `categoryPath` | Source hierarchical category path, or null. |
| `productUrl` | Drogasil product link without tracking query parameters. |
| `currentPrice` | Anonymous storefront selling price in BRL, or null if unavailable. |
| `listPrice` | Source reference/list price in BRL, or null. |
| `discountPercentage` | Source percentage, not independently recomputed. |
| `currency` | Always `BRL`. |
| `inStock` | True for a positive source stock signal, false for zero, null for unknown. |
| `stockSignal` | Raw stock signal; not a guaranteed physical inventory count. |
| `searchQuery`, `sourceUrl` | First query and search page yielding this SKU. |
| `scrapedAt` | UTC snapshot timestamp. |

Source-unavailable scalar values are null, not invented zeros. Missing entire pricing compositions are treated as an upstream failure. A null price does not mean that a product is free.

### Example output

A real source record captured during testing; prices and availability can change:

```json
{
  "sku": "117313",
  "name": "Pratium Paracetamol 140mg/ml Gotas 15ml",
  "brand": "Pratium",
  "categories": ["Medicamentos", "Remédios", "Para Dor e Febre"],
  "categoryPath": "Medicamentos > Remédios > Para Dor e Febre",
  "productUrl": "https://www.drogasil.com.br/pratium-140mg-gotas-frasco-15ml.html",
  "currentPrice": 39.98,
  "listPrice": 39.98,
  "discountPercentage": 0,
  "currency": "BRL",
  "inStock": true,
  "stockSignal": 1,
  "searchQuery": "paracetamol",
  "sourceUrl": "https://www.drogasil.com.br/search?w=paracetamol",
  "scrapedAt": "2026-10-27T07:15:15.330Z"
}
```

### How much does it cost to collect Drogasil product prices?

Pay-per-event billing consists of a **$0.005 start fee** and a per-product event for each unique SKU snapshot delivered. At the BRONZE tier, the product event is **$0.00228 per product**. Other plan tiers have different product prices; check the Actor's Pricing tab for your plan.

| Unique products | BRONZE event total, including start |
| --- | --- |
| 1 | $0.00728 |
| 50 | $0.119 |
| 100 | $0.233 |

Natural zero-result searches incur only the start fee. Failed requests, rejected rows and duplicate SKUs have no product event. A failed run can retain and charge for products delivered before the failure. Dataset export and platform services follow Apify's applicable plan terms.

### Pagination and limits

Collection follows the storefront's numbered search pages and stops at the global unique-product limit or source exhaustion. Up to 30 pages per query are visited; this is not a promise of a complete catalogue. Sponsored rows and repeated SKUs can make source row counts differ from unique dataset counts.

Requests are sequential and paced at least 750 ms apart. Transient network, HTTP 429 and 5xx failures receive at most two retries, with backoff. If Drogasil blocks a request (HTTP 401/403 or a search page without product data), the blocked connection is retired and the run continues on the next identity: direct, two Apify datacenter proxy sessions, then two Brazilian residential proxy sessions. Proxy traffic is included in the per-product price. If every identity is blocked, or on other permanent HTTP errors, redirects, unexpected HTML and GraphQL errors, the run fails with a clear message.

The default run timeout is five minutes. Large or slow searches may need a higher user-selected timeout, but the 30-page and 1000-product limits still apply. Check run status before treating a dataset as complete.

### Integrations and recurring snapshots

Use an Apify Schedule to run the same input daily. Append results to a warehouse keyed by `sku` and `scrapedAt`, then compute changes downstream. The Actor itself does not maintain history, compare runs or send price-change alerts.

Send the default dataset to Google Sheets, Make, Zapier or your own webhook pipeline through Apify integrations. CSV works well for analyst review; JSON preserves arrays and null values for engineering workflows.

The key-value store also contains `RUN_STATS`: request count, response bytes, retry count, search pages, source rows scanned, skipped in-store service listings (such as clinical exams, which are not products and have no product price) and unique rows saved. These are work counters, not a billing invoice.

### API usage

Store the token in an environment variable, never in shared source code. Start one run and retain its returned run ID and default dataset ID.

```bash
curl -X POST \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"searchQueries":["paracetamol"],"maxItems":50}' \
  'https://api.apify.com/v2/acts/automation-lab~drogasil-pharmacy-products-prices/runs'
```

JavaScript with `apify-client`:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/drogasil-pharmacy-products-prices')
  .call({ searchQueries: ['paracetamol'], maxItems: 50 });
if (run.status !== 'SUCCEEDED') throw new Error(`Run ${run.id}: ${run.status}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems({ limit: 50 });
console.log(items);
```

Python with `apify-client`:

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/drogasil-pharmacy-products-prices').call(
    run_input={'searchQueries': ['paracetamol'], 'maxItems': 50})
if run['status'] != 'SUCCEEDED':
    raise RuntimeError(f"Run {run['id']}: {run['status']}")
print(client.dataset(run['defaultDatasetId']).list_items(limit=50).items)
```

### MCP integration

Configure Claude Code with the stable Actor-specific selection:

```bash
claude mcp add --transport http apify \
  'https://mcp.apify.com?tools=automation-lab/drogasil-pharmacy-products-prices'
```

For Claude Desktop, Cursor, and VS Code with compatible remote MCP support:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/drogasil-pharmacy-products-prices"
    }
  }
}
```

Authenticate using your client's supported Apify token flow. Discover actual tool names and argument schemas with `tools/list`. Actor selection also supplies run and storage helpers; it does not expose exactly one tool. Example prompts: “Collect 20 Drogasil paracetamol price snapshots and show SKU, product name, BRL price and stock signal.” Or: “Export 50 Drogasil vitamina C product snapshots for my spreadsheet.”

Start once, retain the returned run ID and follow that same run. A run ID is metadata, not product data. Server waits may end before the run completes; use bounded polling of the same run (for example 2, 4, 8, then 10 seconds, with a 120-second total deadline). A client timeout is not a reason to launch a duplicate. At the deadline report pending with the run ID; on failure label stored rows as partial.

After success, read bounded dataset pages with explicit offset, limit and fields. For model context, an example consumer budget is 20 rows per page, at most 100 source rows and 64 KiB total UTF-8 content, whichever comes first. Enforce bytes host-side before model injection; disclose omissions and continuation offsets. If the client cannot intercept oversized responses, do not claim a hard byte guarantee. Full exports belong in storage, not an unbounded model response. This consumer budget does not change Actor collection limits.

### Legality and responsible use

Prices are anonymous public storefront snapshots, not checkout quotes. Loyalty programmes, CPF discounts, delivery location, subscriptions, Pix and multi-buy offers may differ. This Actor does not calculate personalized, historical or medical recommendations. Search results may include non-medicine retail products.

Use product URLs to verify material decisions. Respect applicable laws, source terms and rate limits. No affiliation with Drogasil is claimed. Do not provide patient information, prescriptions, authentication tokens or personal identifiers as searches.

### Diagnostics and privacy

Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL query strings are removed; reports are retained for 30 days. Keep searches non-personal. Normal product results stay in your Apify dataset under your storage settings. No AI model is used at runtime. Drogasil receives the product searches, Apify hosts the run/storage, and private GlitchTip receives sanitized failure diagnostics. Delete datasets and key-value stores through Apify; their retention follows your account settings. There is no cross-run cache or persistent browser session.

### Troubleshooting and FAQ

**Why did I receive fewer products than requested?** The limit is a ceiling, not a minimum. The source can exhaust its results, duplicates are removed and only 30 pages per query are visited.

**Why is a result not an exact title match?** Drogasil controls its own search relevance and sponsored placements. There is no local exact-phrase filter.

**Can I scrape a category or product URL?** Not with this Actor. Supply search terms instead; URL inputs are rejected.

**What should I do after a blocked or failed run?** Read the run log and status. Keep any already-written dataset rows labelled partial. Do not blindly repeat large runs; reduce the test to one query and report the run URL through the Actor's Issues tab if the problem persists.

**Does stockSignal mean units on a shelf?** No. It is the anonymous storefront's numeric availability signal and can be binary or approximate.

### Related workflows

This Actor is deliberately standalone for Drogasil. It does not claim coverage of other Brazilian pharmacies or join their prices. Export its snapshots to your existing retail analysis pipeline for cross-source comparisons.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/drogasil-pharmacy-products-prices/changelog.md

# Actor input Schema

## `searchQueries` (type: `array`):

1–10 nonblank product search strings, trimmed and processed in order. Drogasil controls relevance, synonyms, sponsored results and ranking; this is not exact phrase matching. Duplicate trimmed queries and product SKUs are removed globally; the first matching query is retained on each row. Up to 30 search pages per query.

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

Global run limit of unique SKU snapshots across all queries, after deduplication. Default 20, range 1–1000; zero/unlimited is unsupported. Collection stops at this limit or source exhaustion, with at most 30 pages per query. Later queries can receive no results when earlier queries fill the limit.

## Actor input object example

```json
{
  "searchQueries": [
    "paracetamol"
  ],
  "maxItems": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset of unique SKUs, BRL prices, brands, categories and stock signals.

## `stats` (type: `string`):

Request, response-byte, page, retry, scanned and saved counters for this run.

# 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 = {
    "searchQueries": [
        "paracetamol"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/drogasil-pharmacy-products-prices").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 = {
    "searchQueries": ["paracetamol"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/drogasil-pharmacy-products-prices").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 '{
  "searchQueries": [
    "paracetamol"
  ],
  "maxItems": 20
}' |
apify call automation-lab/drogasil-pharmacy-products-prices --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/drogasil-pharmacy-products-prices"
        }
    }
}
```

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/78eg2tZkGdqXirwFG/builds/8rCKTKz6zyqD3uCuB/openapi.json
