---
title: "Bing scraper"
description: "Scrape Bing search results as JSON: titles, URLs, snippets, authors, dates, related searches and shopping products. One API request from Python, Node.js, CLI or MCP."
canonical: https://www.zenrows.com/scrape/bing
updated: 2026-10-20
---

# Bing scraper

The Zenrows Bing scraper turns any Bing search URL into structured JSON: organic titles, URLs, displayed URLs, snippets, source names, authors, published dates, related searches and shopping products. You send the URL, Fetch in Adaptive Stealth Mode opens the page, and Extract returns the fields. Run it from an API call, the CLI or an AI agent.

- Site: bing.com
- Returns: Organic results, snippets, related searches and shopping products

## Run it: one Bing search in, JSON out

```json Input
{
  "url": "https://www.bing.com/search?q=best+running+shoes",
  "mode": "auto",
  "extract": "auto"
}
```

```json Output
{
  "search_query": { "text": "best running shoes" },
  "organic_results": [
    {
      "title": "The 15 Best Running Shoes of 2026, Tested by Runner's World",
      "source_name": "Runner's World",
      "author": "Michael Charboneau",
      "displayed_url": "https://www.runnersworld.com › gear › best-running-shoes",
      "published_date": "Aug 3, 2026",
      "rating_value": null,
      "snippet": "Aug 3, 2026 · Find the best running shoes of 2026, including Runner's World-tested picks from Adidas, Brooks, New Balance, Nike, …",
      "url": "https://www.bing.com/ck/a?!&&p=743744e5b5b6dbb7…&u=a1aHR0cHM6Ly93d3cucnVubmVyc3dvcmxkLmNvbS9nZWFyL2ExOTY2MzYyMS9iZXN0LXJ1bm5pbmctc2hvZXMv&ntb=1"
    },
    {
      "title": "10 Best Running Shoes of 2026 | Tested & Ranked - GearLab",
      "source_name": "GearLab",
      "author": "Nathaniel Bailey",
      "displayed_url": "https://www.outdoorgearlab.com › ... › best-running-shoes",
      "published_date": "May 14, 2026",
      "rating_value": 4.8,
      "snippet": "May 14, 2026 · We run more than 50 miles in every pair of shoes we test, putting top models head to head to find the best from Nike, …",
      "url": "https://www.bing.com/ck/a?!&&p=027932b30ff8c467…&ntb=1"
    }
  ],
  "related_searches": [
    { "query_text": "best running shoes for men", "search_url": "https://www.bing.com/ck/a?!&&p=f744033d5b2c2946…&ntb=1" },
    { "query_text": "best cushioned running shoes 2026", "search_url": "https://www.bing.com/ck/a?!&&p=04b500857d736a4c…&ntb=1" }
  ],
  "ai_recommendations": [
    {
      "name": "Brooks Glycerin Max",
      "tagline": "Smooth and bouncy",
      "search_url": "/search?q=Brooks+Glycerin+Max&FORM=SNAPST&filters=…",
      "thumbnail_url": "https://th.bing.com/th/id/OSK.L5k9pT0GrYAl0joR-PEK9waLg_beXvRh3lt_uzdqa_w?w=88&h=88&c=7&rs=1&o=6&pid=SANGAM"
    }
  ],
  "shopping_products": [
    {
      "title": "Nike Womens Vomero 18 - Running Shoes Chalk/Red Stardust/Silt Red Size 06.5",
      "seller_name": "Foot Locker",
      "rating_value": 4.5,
      "free_shipping": true
    }
  ]
}
```

Request and output of a live call to a Bing search page on Oct 20, 2026, trimmed for length. A field is returned when the page shows it.

## What data can you scrape from Bing?

A Bing results page carries more than ten blue links. The scraper returns each block of the page as its own group, so you can keep the organic results and drop the rest, or read the shopping carousel on its own.

| Field | What it holds | Example |
|---|---|---|
| `search_query.text` | The query Bing answered | `best running shoes` |
| `organic_results[]` | The web results in page order, ten on a standard page | `{ "title": "The 15 Best Running Shoes…", … }` |
| `organic_results[].title` | The blue link text | `10 Best Running Shoes of 2026 \| Tested & Ranked - GearLab` |
| `organic_results[].url` | Bing's click URL, with the destination encoded in its `u` parameter | `https://www.bing.com/ck/a?!&&p=…&u=a1aHR0cHM6…` |
| `organic_results[].displayed_url` | The green breadcrumb under the title | `https://www.runnersworld.com › gear › best-running-shoes` |
| `organic_results[].source_name` | The site or publisher name Bing shows | `Runner's World` |
| `organic_results[].author` | The byline, when Bing shows one | `Michael Charboneau` |
| `organic_results[].published_date` | The date shown before the snippet | `Aug 3, 2026` |
| `organic_results[].rating_value` | A star rating from the result's rich snippet | `4.8` |
| `organic_results[].snippet` | The description text under the link | `We run more than 50 miles in every pair…` |
| `related_searches[].query_text` | The related queries at the bottom of the page | `best running shoes for beginners` |
| `related_searches[].search_url` | The link to run that related query | `https://www.bing.com/ck/a?!&&p=…` |
| `ai_recommendations[].name` | Entities in Bing's generated carousel | `Asics Novablast 5` |
| `ai_recommendations[].tagline` | The one-line summary under each entity | `Softer underfoot feel` |
| `shopping_products[].title` | Product listing title in the shopping carousel | `Saucony Ride 19 \| Road Running Shoes` |
| `shopping_products[].seller_name` | The store selling it | `Nordstrom` |
| `shopping_products[].rating_value` | The product's star rating | `4.6` |
| `shopping_products[].free_shipping` | Whether the offer ships free | `true` |

## How to scrape Bing with Zenrows

1. **Create a free Zenrows account** and copy your API key from the dashboard.
2. **Build the Bing search URL.** `https://www.bing.com/search?q=` plus your query, with spaces as `+`. Add `first=11`, `first=21` and so on for later pages, and `setlang` or `mkt` for a language and market.
3. **Choose where the searcher is.** Bing localizes results to the visitor, so set the country you want rankings for. Without it, local results come from wherever the request lands.
4. **Send it with the default configuration**: Adaptive Stealth Mode to open the page and Extract to return the fields. Read `parsed` from the response.
5. **Run your keyword list in Batch** once one query returns what you need, with the keyword as the ID of each result.

```python Python
# pip install requests
import json
import requests

params = {
    "apikey": "YOUR_ZENROWS_API_KEY",
    "url": "https://www.bing.com/search?q=best+running+shoes",
    "mode": "auto",          # Adaptive Stealth Mode
    "extract": "auto",       # structured JSON
    "proxy_country": "us",   # rank results as a US searcher sees them
}
response = requests.get("https://api.zenrows.com/v1/", params=params, timeout=180)
response.raise_for_status()

data = response.json()["parsed"]
for rank, result in enumerate(data["organic_results"], start=1):
    print(rank, result["source_name"], result["title"])
print(json.dumps(data["related_searches"], indent=2))
```

```javascript Node.js
// Node 18+ (built-in fetch)
const params = new URLSearchParams({
  apikey: "YOUR_ZENROWS_API_KEY",
  url: "https://www.bing.com/search?q=best+running+shoes",
  mode: "auto",
  extract: "auto",
  proxy_country: "us",
});

const response = await fetch(`https://api.zenrows.com/v1/?${params}`, {
  signal: AbortSignal.timeout(180_000),
});
if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);

const { parsed } = await response.json();
parsed.organic_results.forEach((r, i) => console.log(i + 1, r.title, r.displayed_url));
```

```bash cURL
curl "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fwww.bing.com%2Fsearch%3Fq%3Dbest%2Brunning%2Bshoes&mode=auto&extract=auto&proxy_country=us"

# Only the organic titles, links and snippets
curl "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fwww.bing.com%2Fsearch%3Fq%3Dbest%2Brunning%2Bshoes&mode=auto&extract=auto&proxy_country=us&extract_fields=organic_results.title%2Corganic_results.url%2Corganic_results.snippet"
```

```python Python SDK
# pip install zenrows
from zenrows import ZenRowsClient

client = ZenRowsClient("YOUR_ZENROWS_API_KEY")
response = client.get(
    "https://www.bing.com/search?q=best+running+shoes&first=11",
    params={"mode": "auto", "extract": "auto", "proxy_country": "us"},
)
for result in response.json()["parsed"]["organic_results"]:
    print(result["title"], result.get("published_date"))
```

## Input

The scraper takes one Bing URL per request. The query, page and market live in the URL itself, and the options below control how Zenrows opens it. The same options apply to every task of a Batch job.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `url` | string | required | A Bing search URL: `https://www.bing.com/search?q=…`, with `first` for the page offset and `setlang` or `mkt` for language and market |
| `mode` | string | `auto` | Adaptive Stealth Mode: starts with the lightest setup and adds rendering and protected-site handling only when the page needs them |
| `extract` | string | `auto` | Returns the results page as JSON in `parsed`, next to the raw `html` |
| `extract_fields` | string | all fields | Comma-separated paths to keep, such as `organic_results.title,organic_results.url,related_searches` |
| `proxy_country` | string | any | Two-letter country code. Bing ranks and localizes results by the searcher's location |
| `wait_for` | string | none | A CSS selector to wait for before the page is read |
| `session_id` | integer | none | Keep the same session across several pages of one query, up to 10 minutes |

```json Batch input
{
  "type": "regular",
  "status": "closed",
  "zenrows_params": {
    "mode": "auto",
    "extract": "auto",
    "proxy_country": "us"
  },
  "tasks": [
    { "url": "https://www.bing.com/search?q=best+running+shoes", "external_id": "best-running-shoes-p1" },
    { "url": "https://www.bing.com/search?q=best+running+shoes&first=11", "external_id": "best-running-shoes-p2" },
    { "url": "https://www.bing.com/search?q=trail+running+shoes", "external_id": "trail-running-shoes-p1" }
  ]
}
```

## Output

Every response is JSON with two keys: `html`, the results page as Bing served it, and `parsed`, the structured record. Blocks Bing did not show for a query come back as empty arrays, so your code can read every key without checking first. The sample below is a trimmed live response.

```json Search results
{
  "search_query": { "text": "best running shoes" },
  "organic_results": [
    {
      "title": "The 15 Best Running Shoes of 2026, Tested by Runner's World",
      "source_name": "Runner's World",
      "author": "Michael Charboneau",
      "displayed_url": "https://www.runnersworld.com › gear › best-running-shoes",
      "published_date": "Aug 3, 2026",
      "rating_value": null,
      "snippet": "Aug 3, 2026 · Find the best running shoes of 2026, including Runner's World-tested picks from Adidas, Brooks, New Balance, Nike, …",
      "url": "https://www.bing.com/ck/a?!&&p=743744e5b5b6dbb7…&ntb=1"
    },
    {
      "title": "The 7 Best Running Shoes of 2026 | Reviews by Wirecutter",
      "source_name": "New York Times",
      "author": null,
      "displayed_url": "https://www.nytimes.com › wirecutter › reviews › best-running-shoes",
      "published_date": "Sep 21, 2026",
      "rating_value": null,
      "snippet": "Sep 21, 2026 · Our focus: go-to shoes for everyday runs. We take a look at the two main running shoe types (neutral and …",
      "url": "https://www.bing.com/ck/a?!&&p=6410d5c375b62024…&ntb=1"
    }
  ],
  "related_searches": [
    { "query_text": "best budget running shoes 2026", "search_url": "https://www.bing.com/ck/a?!&&p=…&ntb=1" },
    { "query_text": "best running shoes for beginners", "search_url": "https://www.bing.com/ck/a?!&&p=…&ntb=1" }
  ],
  "ai_recommendations": [
    {
      "name": "Asics Novablast 5",
      "tagline": "Softer underfoot feel",
      "search_url": "/search?q=Asics+Novablast+5&FORM=SNAPST&filters=…",
      "thumbnail_url": "https://th.bing.com/th/id/OSK.8BdoRyrwS7qz7ZvRIHD71XkHbbCbyZluqjzBE7H_s2o?w=88&h=88&c=7&rs=1&o=6&pid=SANGAM"
    }
  ],
  "shopping_products": [
    {
      "title": "ASICS(R) GEL-NIMBUS(R) 28 Running Shoe In Prussian Blue/Cream At Nordstrom, Size 12",
      "seller_name": "Nordstrom",
      "rating_value": 4.6,
      "free_shipping": true,
      "thumbnail_url": "https://th.bing.com/th?id=OPHS.Y%2b2U4RobIpumsw474C474&w=150&h=124&o=5&pid=21.1"
    }
  ]
}
```

Organic `url` values are Bing click links. The destination sits in the `u` parameter after the `a1` prefix, base64url-encoded: `aHR0cHM6Ly93d3cucnVubmVyc3dvcmxkLmNvbS9nZWFyL2ExOTY2MzYyMS9iZXN0LXJ1bm5pbmctc2hvZXMv` decodes to `https://www.runnersworld.com/gear/a19663621/best-running-shoes/`. Decode it in your pipeline when you need the final domain, or read `displayed_url` for a readable version.

Need a spreadsheet? Load `organic_results` into pandas with `pd.json_normalize(...)` and write CSV. Need the page for an LLM? Ask for Markdown instead of JSON.

## Scrape Bing from your coding agent

Claude Code, Cursor, Codex and any MCP client can search Bing and read the results from a prompt.

The agent sends the same Fetch and Extract request shown above, so it reads the organic results, related searches and shopping products as JSON. Connect the Zenrows MCP server once, or install the CLI and let the agent call it in the terminal.

```bash Connect the MCP server (Claude Code)
claude mcp add zenrows -e ZENROWS_API_KEY=YOUR_ZENROWS_API_KEY -- npx -y @zenrows/mcp
```

```json MCP config (Cursor, Claude Desktop, Windsurf)
{
  "mcpServers": {
    "zenrows": {
      "command": "npx",
      "args": ["-y", "@zenrows/mcp"],
      "env": { "ZENROWS_API_KEY": "YOUR_ZENROWS_API_KEY" }
    }
  }
}
```

```bash Or run the CLI
npx -y @zenrows/cli init
zenrows extract "https://www.bing.com/search?q=best+running+shoes" --proxy-country us
```

```text Then ask your agent
Use Zenrows to search Bing from the US for "best running shoes" and
"trail running shoes". For each query, list the top 10 organic results
with position, source name, published date and the decoded destination
URL, then tell me which domains rank for both.
```

## Scrape Bing at scale with Batch and Crawl

**Batch** runs a keyword list as one job. Build one Bing URL per keyword and page, set the country once for the whole job, and put the keyword in `external_id` so every result maps back to it. Run it daily for rank tracking across hundreds or thousands of queries.

**Crawl** follows links from a start URL and returns every page it reaches on that site. On Bing, start on a results page and keep only the links that contain `/search?q=`: Crawl then walks the related searches and pagination links, which is a quick way to map the query space around a seed keyword. Send the URLs it finds to Batch with Extract to get the structured results.

```bash Batch (cURL)
curl -X POST "https://async.api.zenrows.com/v1/jobs" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "regular",
    "status": "closed",
    "zenrows_params": { "mode": "auto", "extract": "auto", "proxy_country": "us" },
    "tasks": [
      { "url": "https://www.bing.com/search?q=best+running+shoes", "external_id": "best-running-shoes" },
      { "url": "https://www.bing.com/search?q=trail+running+shoes", "external_id": "trail-running-shoes" }
    ]
  }'

# Read the results when the job finishes
curl "https://async.api.zenrows.com/v1/jobs/JOB_ID/results?status=successful" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY"
```

```bash Batch (CLI)
# keywords.jsonl: one {"url": "https://www.bing.com/search?q=...", "external_id": "...", "extract": "auto"} per line
zenrows batch create keywords.jsonl --proxy-country us --wait
zenrows batch results <job-id> --out bing-results.jsonl
```

```bash Crawl (cURL)
curl -X POST "https://api.zenrows.com/v1/crawls" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.bing.com/search?q=best+running+shoes",
    "depth": 2,
    "max_pages": 100,
    "include_patterns": ["/search?q="]
  }'
```

**Scheduled jobs** run the same Batch job on a timetable, on Zenrows' side: every few hours, once a day, at set times on chosen days, or once at a future date. Each run keeps its own results, a webhook can tell your app when a run finishes, and you can pause or resume the schedule at any time, with no cron server to keep alive.

```bash Scheduled job (cURL)
# Runs every day on Zenrows' side; each run keeps its own results
curl -X POST "https://async.api.zenrows.com/v1/jobs" \
  -H "X-API-Key: YOUR_ZENROWS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "type": "scheduled",
      "status": "closed",
      "schedule": {
        "rate": {
          "every": 1,
          "unit": "day"
        }
      },
      "zenrows_params": {
        "mode": "auto",
        "extract": "auto"
      },
      "tasks": [
        {
          "url": "https://www.bing.com/search?q=best+running+shoes",
          "external_id": "bing"
        }
      ]
    }'

# Or at set times: "schedule": { "calendar": { "times_of_day": ["09:00"],
#   "cadence": { "weekly": { "days": ["mon", "thu"] } } }, "timezone": "Europe/Madrid" }
```

## What teams do with Bing data

| Use case | Data they pull | Who runs it |
|---|---|---|
| Rank tracking on Bing | Position, title, displayed URL and destination for each keyword, per country | SEO teams and agencies |
| Search engine comparison | The same keyword list on Bing and Google, compared domain by domain | SEO and content strategy teams |
| Content gap research | Publishers, authors and publish dates of the pages that rank, plus related searches | Content and editorial teams |
| Shopping visibility | Product titles, sellers, ratings and free shipping in Bing's shopping carousel | Ecommerce and retail media teams |
| Grounding AI answers | Fresh organic results and snippets for a question, fed to an LLM with their sources | AI and data teams building agents |
| Brand and reputation monitoring | Who ranks for your brand name and what the snippets say | PR, brand and communications teams |

## Tips for scraping Bing

- **Page with `first`, not `page`.** Bing uses an offset: `first=1` is page one, `first=11` page two, `first=21` page three. Build those URLs up front and send them in one Batch job.
- **Set market and country together.** `mkt=en-GB` asks for the UK market, and requesting from the UK makes the local results match. Mixing a market with a different country gives you rankings no real searcher sees.
- **Decode the click URLs.** Organic links go through `bing.com/ck/a`. Take the `u` parameter, drop the leading `a1`, and base64url-decode the rest to get the destination page.
- **Keep empty blocks in your schema.** `shopping_products` and `ai_recommendations` appear only for queries where Bing shows them, so store them as optional and count them per keyword.
- **Store the query and the date with every result.** Bing changes rankings daily, and the result has no capture date of its own. Use `external_id` for the keyword and stamp the run date in your pipeline.
- **Narrow the response for rank tracking.** If you only need titles, links and snippets, list those fields and the response drops the rest, which keeps stored results small.

## Frequently asked questions

### Is it legal to scrape Bing?

Collecting public search results from Bing, such as titles, links and snippets shown to every visitor, is common practice for SEO and market research. Results can include names of authors and people in the news, and personal data falls under laws such as the GDPR and the CCPA, so keep only what you have a legitimate reason to use. Check Microsoft's terms for your use case and ask your lawyer if you are unsure.

### Is there an official Bing search API?

Microsoft retired the Bing Search APIs on August 11, 2025. Its suggested replacement, Grounding with Bing Search, runs inside Azure AI agents and returns answers for an agent to use, not the results page with positions, snippets and shopping blocks. Teams that need the results as a searcher sees them scrape the Bing results page.

### What Bing pages can I scrape?

Web search results pages ( bing.com/search?q=… ) on any page of results, in any market and language Bing offers. The response includes the organic results, related searches, shopping products and Bing's generated recommendations when the page shows them.

### How do I scrape Bing results for a specific country?

Set the country in the request so Zenrows opens Bing from that location, and add the matching mkt and setlang values to the URL. To compare markets, send the same query once per country in a single Batch job.

### How do I scrape Bing with Python?

Send a GET request to https://api.zenrows.com/v1/ with your API key, the Bing search URL, Adaptive Stealth Mode and Extract, as in the Python example above. parsed["organic_results"] is a list of dictionaries in page order. The zenrows package on PyPI wraps the same request.

### How many Bing results can I get per query?

A standard results page holds about ten organic results, and later pages come from the first offset. To collect the first 50 results for a keyword, request five page URLs. For many keywords, send all of their pages in one Batch job, which accepts more than 10,000 URLs.

### How do I get the real URL of a Bing result?

The url field is Bing's click-tracking link. The destination is in its u parameter: remove the a1 prefix and base64url-decode the rest. The displayed_url field gives the readable domain and path when you only need to know who ranks.

### Can AI agents scrape Bing with Zenrows?

Yes. Connect the Zenrows MCP server to Claude, Cursor, Codex or any MCP client, or give your agent the Zenrows CLI. Ask it to search Bing for a query and it calls Fetch and Extract, then reads the results as JSON.

### Can I scrape Bing on a schedule?

Yes. Create a scheduled Batch job with your Bing URLs and the same settings as a single request, and Zenrows runs it on its side: every few hours, once a day, at set times on chosen days, or once at a future date. Each run keeps its own results, a webhook can notify your app when a run finishes, and the schedule can be paused or resumed at any time.

### Which integrations work with the Bing scraper?

Zenrows works with n8n, Make, Zapier, Clay, Dify, LangChain, LlamaIndex, CrewAI and Mastra, plus the Python, Node.js and Go SDKs and any HTTP client. A scheduled workflow can run your keyword list and write positions to Google Sheets or a database. See the integrations page for the full list.

### What format does the data come in?

JSON by default, with the structured results in parsed and the original page in html . You can also ask for the page as Markdown or plain text, which suits an LLM that needs to read the results with their sources.

All scrapers: https://www.zenrows.com/scrape. Start free: https://app.zenrows.com/register. Docs: https://docs.zenrows.com
