# Baidu Maps Scraper (`searchapi/baidu-maps-scraper`) Actor

Scrape points-of-interest (POI) from Baidu Maps. Extracts business names, addresses, phones, ratings, reviews, hours, coordinates, and categories. Supports pagination and region filter.

- **URL**: https://apify.com/searchapi/baidu-maps-scraper.md
- **Developed by:** [Search API](https://apify.com/searchapi) (community)
- **Categories:** Automation, Developer tools, Lead generation
- **Stats:** 12 total users, 0 monthly users, 4.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.99 / 1,000 search 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?

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

## Baidu Maps Scraper

Search Baidu Maps by POI keyword and city/region and export normalized place records. The Actor uses Baidu's structured search response when it is available and falls back to the rendered result cards when the response shape changes.

### Input

| Field | Required | Default | Description |
| --- | :---: | --- | --- |
| `query` | yes | `餐厅` | Primary POI search term. Chinese keywords usually return the best coverage. |
| `queries` | no | `[]` | Up to 19 additional search terms processed in the same run. |
| `region` | yes | `北京` | City or region appended through the Baidu Maps search interface. |
| `maxItems` | no | `100` | Maximum records across all queries after global deduplication. |
| `maxItemsPerQuery` | no | `100` | Per-query collection cap used for fair interleaving. |
| `maxPages` | no | `10` | Maximum pages processed for each query. |
| `requestDelayMs` | no | `0` | Delay between same-page pagination requests. |
| `maxConcurrency` | no | `3` | Concurrent independent query searches, from 1 to 5. |
| `market` | no | `zh-CN` | Locale used in normalized search context fields. |
| `maxRequestRetries` | no | `3` | Bounded retries for temporary browser, network, and proxy failures. |
| `navigationTimeoutSecs` | no | `60` | Per-navigation timeout. |
| `requestHandlerTimeoutSecs` | no | `120` | Per-query handler timeout. |
| `categoryContains` | no | — | Case-insensitive category/tag filter. |
| `minRating` | no | — | Minimum source rating from 0 to 5. |
| `minReviewCount` | no | — | Minimum parsed review count. |
| `openNowOnly` | no | `false` | Keep only POIs reported as open. |
| `sortBy` | no | `relevance` | `relevance`, `nameAsc`, `nameDesc`, `ratingDesc`, `reviewCountDesc`, or `distanceAsc`. |
| `proxyConfiguration` | no | no proxy | Standard Apify or custom proxy configuration. |
| `blockMedia` | no | `false` | Optional developer optimization that aborts media/font requests; leave disabled if the target UI needs them. |

### Output

The dataset schema documents 86 typed fields. Every record includes the stable common contract: `id`, `type`, `resultType`, `position`, `globalPosition`, `queryPosition`, `page`, `name`, `nameLocal`, `region`, `country`, `source`, `engineId`, `searchQuery`, `query`, `searchUrl`, `market`, `language`, `extractionMethod`, `scrapedAt`, and `searchMetadata`.

Depending on what Baidu exposes for an individual POI, records can also include:

- Baidu identity: `uid`, `poiId`, `category`, `categoryCode`, `categories`, and `tags`.
- Location: address components, numeric latitude/longitude, and `coord`. Projected map coordinates are never mislabeled as geographic degrees.
- Contact: phone, website, and email.
- Reputation and pricing: rating, review counts, price, numeric price, price level, and currency.
- Operations: opening hours, open status, business status, verification/claim status, and chain information.
- Media and features: description, thumbnail, images/photos, facilities, and payment options.
- Navigation and provenance: POI URLs, canonical URL, domain, source, extraction mode, and normalized search context.
- Transport provenance: parsed API total, HTTP status, response content type, and API response count when available.

The `OUTPUT` key-value record reports status, per-query counts, pagination progress, API/DOM usage, duplicate and filter counts, applied filters, sort order, and failed/no-result query positions.

Unavailable optional fields are omitted rather than emitted as `null`, empty strings, empty arrays, or empty objects.

### Pagination, limits, and deduplication

Pagination is performed inside the same live Baidu Maps SPA page so search and session state are preserved. Records are deduplicated by Baidu UID when available, otherwise by a stable SHA-256 key derived from name, address, query, and region. `maxItemsPerQuery` buffers each query independently; relevance output is round-robin interleaved and then capped by the global `maxItems`. Other `sortBy` values are applied after interleaving and global deduplication.

An explicit no-results response completes successfully with an empty dataset. Selector/API drift raises an error instead of silently reporting success. Verification and CAPTCHA responses fail closed and are never stored.

When the local system resolver cannot resolve `map.baidu.com`, the Actor may use a bounded public-DNS lookup only to map the official hostname inside the browser. It does not replace the official hostname or bypass Baidu verification.

### Proxy and access boundaries

Residential proxy configuration can improve ordinary geographic availability and rate-limit resilience. The Actor does not solve or bypass interactive verification, authentication, account restrictions, or other access controls. If Baidu presents an explicit challenge, the run stops with an empty dataset.

After a successful run, download the dataset JSON from the run's default dataset storage or the Apify dataset API/Console links. The `OUTPUT` key-value record remains available even when Baidu blocks the run.

A challenge is reported as `errorCode: TARGET_VERIFICATION` in the run log and query summary, with `failureCategories: ["challenge"]` in `OUTPUT`; the per-query summary retains the observed HTTP status and response content type without storing the response body.

### Example

```json
{
  "query": "咖啡厅",
  "queries": ["酒店", "公园"],
  "region": "北京",
  "maxItems": 50,
  "maxItemsPerQuery": 25,
  "maxPages": 3,
  "maxConcurrency": 3,
  "sortBy": "ratingDesc",
  "minRating": 4,
  "minReviewCount": 20,
  "requestDelayMs": 300,
  "blockMedia": false,
  "market": "zh-CN",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "countryCode": "CN"
  }
}
```

# Changelog

This Actor's version history is a separate document: https://apify.com/searchapi/baidu-maps-scraper/changelog.md

# Actor input Schema

## `query` (type: `string`):

POI search query (e.g. 餐厅, 咖啡厅, 酒店)

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

Optional additional POI searches to run in the same Actor invocation.

## `region` (type: `string`):

City/region name to search within (e.g. 北京, 上海, 深圳)

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

Maximum number of POIs to scrape

## `maxItemsPerQuery` (type: `integer`):

Maximum records buffered for each search before the global maxItems cap and fair interleaving.

## `maxPages` (type: `integer`):

Maximum number of pagination pages to follow

## `requestDelayMs` (type: `integer`):

Optional pause between same-page Baidu Maps pagination requests.

## `maxConcurrency` (type: `integer`):

Number of independent query searches processed concurrently.

## `market` (type: `string`):

Locale tag (e.g. zh-CN)

## `maxRequestRetries` (type: `integer`):

Retry temporary browser, network, and proxy failures.

## `navigationTimeoutSecs` (type: `integer`):

Maximum time allowed for each page navigation.

## `requestHandlerTimeoutSecs` (type: `integer`):

Maximum time allowed for search interaction and extraction.

## `categoryContains` (type: `string`):

Keep POIs whose category or tags contain this text.

## `minRating` (type: `number`):

Keep POIs with a source rating at or above this value.

## `minReviewCount` (type: `integer`):

Keep POIs with a parsed review count at or above this value.

## `openNowOnly` (type: `boolean`):

Keep only POIs for which Baidu reports an open status.

## `sortBy` (type: `string`):

Sort after fair multi-query interleaving and global deduplication.

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

Proxy configuration for the scraper

## `blockMedia` (type: `boolean`):

Abort media and font requests to reduce bandwidth. Keep disabled if the target UI needs those resources.

## Actor input object example

```json
{
  "query": "餐厅",
  "queries": [],
  "region": "北京",
  "maxItems": 100,
  "maxItemsPerQuery": 100,
  "maxPages": 10,
  "requestDelayMs": 0,
  "maxConcurrency": 3,
  "market": "zh-CN",
  "maxRequestRetries": 3,
  "navigationTimeoutSecs": 60,
  "requestHandlerTimeoutSecs": 120,
  "openNowOnly": false,
  "sortBy": "relevance",
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "blockMedia": false
}
```

# Actor output Schema

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

No description

## `datasetConsole` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# 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 = {
    "query": "餐厅",
    "region": "北京",
    "maxItems": 100,
    "maxPages": 10,
    "market": "zh-CN",
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("searchapi/baidu-maps-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 = {
    "query": "餐厅",
    "region": "北京",
    "maxItems": 100,
    "maxPages": 10,
    "market": "zh-CN",
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("searchapi/baidu-maps-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 '{
  "query": "餐厅",
  "region": "北京",
  "maxItems": 100,
  "maxPages": 10,
  "market": "zh-CN",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call searchapi/baidu-maps-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,searchapi/baidu-maps-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/sSfMITEPqBErRzteM/builds/UZQZ4FVOwgnHfXWlf/openapi.json
