Scrape Bing Search: A Practical Technical Guide
Article

Scrape Bing Search: A Practical Technical Guide

Guide

Bing scraping blocked? Discover how to bypass rate limits and bot detection to extract URLs, titles, and SEO data with our practical Python Bing scraper guide.

Scraping Bing search results is useful for SEO monitoring, research, and competitive analysis. Bing is usually easier to scrape than some other search engines, but it still applies rate limits and bot detection that can break naive scripts.

A typical Bing scraper extracts:

  • Result titles
  • URLs
  • Descriptions
  • Ranking position

These fields are enough to build rank trackers, keyword research tools, or datasets for analysis. This guide focuses on building a working scraper with code examples and realistic constraints.

Understanding Bing Search URLs

The basic Bing search endpoint looks like this: https://www.bing.com/search?q=python+web+scraping

Useful parameters:

Parameter Description
q Search query
first Offset for pagination
count Results per page
setmkt Market/language

Example: https://www.bing.com/search?q=web+scraping&count=10&first=11

This returns the second page of results. Pagination usually increments the first parameter by the number of results per page.

Basic Python Bing Scraper

Start with a simple scraper using requests and BeautifulSoup.

Install dependencies:

pip install requests beautifulsoup4

Basic example:

import requests
from bs4 import BeautifulSoup

url = "https://www.bing.com/search?q=python+scraping"

headers = {
    "User-Agent": "Mozilla/5.0"
}

response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, "html.parser")

results = soup.select("li.b_algo")

for r in results:
    title = r.select_one("h2").get_text(strip=True)
    link = r.select_one("h2 a")["href"]
    desc = r.select_one(".b_caption p")

    description = desc.get_text(strip=True) if desc else ""

    print(title)
    print(link)
    print(description)
    print("-" * 40)

Typical organic results appear inside li.b_algo. Each result usually contains:

  • h2 → title
  • h2 a → link
  • .b_caption p → description

This structure has stayed relatively stable across Bing versions.

Adding Pagination

A real scraper needs more than one page.

Example:

import requests
from bs4 import BeautifulSoup
import time

query = "python scraping"
results_per_page = 10

headers = {
    "User-Agent": "Mozilla/5.0"
}

for page in range(0, 50, results_per_page):
    url = f"https://www.bing.com/search?q={query}&count=10&first={page+1}"
    response = requests.get(url, headers=headers)
    soup = BeautifulSoup(response.text, "html.parser")

    for r in soup.select("li.b_algo"):
        title = r.select_one("h2").get_text(strip=True)
        link = r.select_one("h2 a")["href"]
        print(title, link)

    time.sleep(2)

The delay is important. Without it, Bing will start rejecting requests. Bing applies rate limiting and bot detection that can block aggressive scrapers.

Using Proxies

Even moderate scraping volumes require proxies. When scaling up, manual management of IPs becomes a headache. For a deeper look at why this is necessary, you might find this guide on the best tools for Bing rank tracking helpful, as it highlights how automated systems handle these blocks.

Example:

proxies = {
    "http": "http://user:pass@proxy-ip:port",
    "https": "http://user:pass@proxy-ip:port"
}

response = requests.get(
    url,
    headers=headers,
    proxies=proxies,
    timeout=20
)

Without IP rotation you will eventually see:

  • CAPTCHA pages
  • HTTP 403 errors
  • Empty responses

Search engines track request patterns and block repeated queries from a single IP.


Handling Timeouts and Retries

Network failures happen often during scraping. Always retry.

Example:

import requests
import time

def fetch(url):
    for attempt in range(5):
        try:
            r = requests.get(
                url,
                headers={"User-Agent": "Mozilla/5.0"},
                timeout=10
            )
            if r.status_code == 200:
                return r.text
        except requests.exceptions.RequestException:
            pass
        time.sleep(2)
    return None

This avoids crashes when requests fail.


Scraping Bing Images

Bing images use a different endpoint: https://www.bing.com/images/async?q=cats&first=1&mmasync=1

Images load asynchronously, and metadata appears inside JSON attributes in HTML elements.

Example:

import requests
from bs4 import BeautifulSoup

url = "https://www.bing.com/images/async?q=cats&first=1&mmasync=1"
headers = {"User-Agent": "Mozilla/5.0"}

r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, "html.parser")

for a in soup.select("a.iusc"):
    data = a.get("m")
    print(data)

This returns structured image metadata.


Conclusion

Scraping Bing search results is straightforward at a small scale. A few lines of Python can extract titles and URLs in minutes. Scaling is the hard part. Blocking, rate limits, and layout changes appear quickly once the request volume grows.

Once those pieces are in place, Bing becomes a reliable data source for ranking tools, research projects, and analytics pipelines.

Table of Contents

    Take a Taste of Easy Scraping!