---
title: "How to Scrape Pinterest in 2026"
slug: how-to-scrape-pinterest
date: 2025-02-19T10:04:57+00:00
modified: 2026-08-25T08:36:00+00:00
permalink: https://brightdata.com/blog/web-data/how-to-scrape-pinterest
type: blog
---

[ Blog ](https://brightdata.com/blog "Blog") / [Web Data](https://brightdata.com/blog/web-data)







 [Web Data](https://brightdata.com/blog/web-data)

# How to Scrape Pinterest in 2026

Learn how to extract dynamic Pinterest data using Python, headless browsers, and automated scraper APIs for fast, scalable results.

 11 min read





 [ ](https://brightdata.com/blog/authors/jake-nulty)

 [Jake Nulty

Technical Writer

 ](https://brightdata.com/blog/authors/jake-nulty)





 ![How to Scrape Pinterest blog image](https://media.brightdata.com/2025/02/How-to-Scrape-Pinterest.svg)





Extracting data from [Pinterest](https://www.pinterest.com/) is different from most [HTML scraping jobs](/blog/how-tos/html-web-scraping). Pinterest builds its pin grid entirely in the browser. The page does ship JSON blobs, such as `__PWS_DATA__` and `__PWS_INITIAL_PROPS__`. Those hold app config and routing data, not pins. That means a plain HTTP request returns no pin data at all. You either drive a real browser, or you call Bright Data’s [Pinterest Scraper API](/products/web-scraper/pinterest).

If you decide to follow along, you’ll learn how to collect Pinterest data using the following methods:

- Extract Pinterest Data With Playwright
- Extract Pinterest Data With Bright Data’s Pinterest Scraper API

## TL;DR: Two Ways to Scrape Pinterest

PlaywrightBright Data Scraper API**Setup**Install Playwright plus browsersInstall Requests, add an API key**Handles blocks**You manage user agents and proxiesHandled for you**Data returned**Title, pin URL, thumbnailFull pin record, user, engagement, hashtags**Scope**Pins visible on one search pageCrawls the keyword, then scrapes every pin**Breaks when**Pinterest changes its markupManaged by Bright Data**Cost**Free, plus your own proxy spend5,000 records a month free, then usage-based## <a></a>What Can You Extract?

Open Pinterest in your browser and inspect a pin. Each one sits deeply nested inside a `div` with `data-test-id="pinWrapper"`.

Find those objects on the page, and you can extract their data:

- The title of each pin.
- The url pointing directly to the pin.
- The image of the pin from the search results.

## <a></a>Scraping Pinterest With Playwright

### <a></a>Getting Started

There are a lot of great [scraping libraries in Python](/blog/web-data/python-web-scraping-libraries), and we’ll be using Playwright. First, you need to make sure you have Playwright installed. You can view their docs [here](https://playwright.dev/python/docs/intro). Playwright is one of the best [headless browsers](/blog/web-data/best-headless-browsers) available.

#### <a></a>Install Playwright

```none
pip install playwright

```

#### <a></a>Install Playwright’s Browsers

```none
playwright install

```

### <a></a>Scraping the Actual Pins

Now, let’s look at how to scrape the actual pins from Pinterest. In the code below, we create two functions, `scrape_pins()` and `main()`. `scrape_pins()` opens a browser and extracts data from Pinterest. `main()` gets used as an entry point for the async runtime.

```none
import asyncio
from playwright.async_api import async_playwright
import json

user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36"

async def scrape_pins(query):
    search_url = f"https://www.pinterest.com/search/pins/?q={query}&rs=typed"
    scraped_data = []

    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page(user_agent=user_agent)
        response = await page.goto(search_url)
        await asyncio.sleep(2)
        try:
            #find the pins on the page
            pins = await page.query_selector_all("div[data-test-id='pinWrapper']")

            #iterate through the pins and extract data
            for pin in pins:
                title_link = await pin.query_selector("a")
                pin_url = await title_link.get_attribute("href")
                title = await title_link.get_attribute("aria-label")
                img = await title_link.query_selector("img")
                img_src = await img.get_attribute("src")

                extracted_data = {
                    "title": title,
                    "url": pin_url,
                    "img": img_src
                }
                #add the data to our results
                scraped_data.append(extracted_data)
        except Exception as e:
            print(f"Failed to scrape pins at {search_url}: {e}")
        finally:
            await browser.close()
    #everything has finished, return our scraped data
    return scraped_data

async def main():
    search_query = "office"
    office_results = await scrape_pins(search_query)

    with open(f"{search_query}-results.json", "w") as file:
        try:
            json.dump(office_results, file, indent=4)
        except Exception as e:
            print(f"Failed to save results: {e}")

if __name__ == "__main__":
    asyncio.run(main())

```

`scrape_pins()` performs the following steps during our scrape:

- Create our url: `search_url`.
- Create an array to hold our results, `scraped_data`.
- Open a new browser instance.
- Set a custom `user_agent` in order to run in headless mode. Without it, Pinterest will block us. Keep this string close to a current Chrome release, because a stale version is easy to flag.
- We wait two seconds for content to load with `asyncio.sleep(2)`.
- We find all of the visible pins on the page using this selector: `div[data-test-id='pinWrapper']`.
- For each pin, we extract the following data:
    - `title`: The title of the pin.
    - `url`: The url leading directly to the pin.
    - `img`: The image of the pin displayed in the search results.

Here is some sample data from the Playwright scraper above.

```none
[
    {
        "title": "A minimalist office featuring a soothing color palette of whites, greys, and natural wood accents, creating a calm and spacious feel3",
        "url": "/pin/10203536650743650/",
        "img": "https://i.pinimg.com/236x/b3/21/e2/b321e2485da40c0dde2685c3a4fdcb56.jpg"
    },
    {
        "title": "a home office with two desks and an open door that leads to the outside",
        "url": "/pin/261912534574291013/",
        "img": "https://i.pinimg.com/236x/56/f1/29/56f129512885e1b3c9971b16f9445c9a.jpg"
    },
    {
        "title": "home office decor, blakc home office, dark home office, moody home office, small home office",
        "url": "/pin/60094976273327121/",
        "img": "https://i.pinimg.com/236x/ba/75/c9/ba75c9be7e635cce3ee80acdf70d6f9f.jpg"
    },
    {
        "title": "an office with a desk, chair and bookshelf in the middle of it",
        "url": "/pin/599682506666665720/",
        "img": "https://i.pinimg.com/236x/57/66/1d/57661dc80bebda3dfe946c070ee8ed13.jpg"
    },
    {
        "title": "a home office with green walls and plants on the shelves, along with a computer desk",
        "url": "/pin/1147080967585091410/",
        "img": "https://i.pinimg.com/236x/ce/e8/b7/cee8b74151b29605a80e0f61898c249d.jpg"
    },

```

## <a></a>Scraping Pinterest With the Bright Data Scraper API

With our Pinterest Scraper API, you can completely automate this process. You do not have to worry about headless browsers, selectors, or anything else.

Make sure you’ve got [Python Requests](/blog/web-data/python-requests-guide) installed.

#### <a></a>Install Requests

```none
pip install requests

```

After you’ve set up your API call, you can trigger it from Python. Below, we also have two functions: `get_pins()` and `poll_and_retrieve_snapshot()`.

- `get_pins()`: This function takes a `keyword` alongside your `api_key`. It then creates and sends a request to our scraper API. This request triggers a scrape of Pinterest for your desired keyword.
- `poll_and_retrieve_snapshot()` takes your `api_key` and the `snapshot_id`. It then checks every 10 seconds to see if the snapshot is ready. Once the snapshot is ready, the data is downloaded and we exit the function.

```none
import requests
import json
import time

#function to trigger the scrape
def get_pins(api_key, keyword):
    url = "https://api.brightdata.com/datasets/v3/trigger"
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    }
    params = {
        "dataset_id": "gd_lk0sjs4d21kdr7cnlv",
        "include_errors": "true",
        "type": "discover_new",
        "discover_by": "keyword",
    }
    data = [
        {"keyword":keyword},
    ]
    #trigger the scrape
    response = requests.post(url, headers=headers, params=params, json=data)
    #return the snapshot_id
    return response.json()["snapshot_id"]

def poll_and_retrieve_snapshot(api_key, snapshot_id, output_file="snapshot-data.json"):
    #create the snapshot url
    snapshot_url = f"https://api.brightdata.com/datasets/v3/snapshot/{snapshot_id}?format=json"
    headers = {
        "Authorization": f"Bearer {api_key}"
    }

    print(f"Polling snapshot for ID: {snapshot_id}...")

    while True:
        response = requests.get(snapshot_url, headers=headers)

        if response.status_code == 200:
            print("Snapshot is ready. Downloading...")
            snapshot_data = response.json()
            #write the snapshot to a new json file
            with open(output_file, "w", encoding="utf-8") as file:
                json.dump(snapshot_data, file, indent=4)
            print(f"Snapshot saved to {output_file}")
            break
        elif response.status_code == 202:
            print("Snapshot is not ready yet. Retrying in 10 seconds...")
        else:
            print(f"Error: {response.status_code}")
            print(response.text)
            break

        time.sleep(10)

if __name__ == "__main__":

    API_KEY = "YOUR-BRIGHT-DATA-API-KEY"
    KEYWORD = "office"

    snapshot_id = get_pins(API_KEY, KEYWORD)
    poll_and_retrieve_snapshot(API_KEY, snapshot_id)

```

Here is some sample data from the downloaded file. Since our trigger request had `"include_errors": "true"`, the file also included pins with errors. The sample data below includes two error pins as well as two pins with good data.

```none
[
    {
        "post_type": null,
        "timestamp": "2026-02-17T15:26:17.248Z",
        "input": {
            "url": "https://www.pinterest.com/pin/jh46IGe2",
            "discovery_input": {
                "keyword": "office"
            }
        },
        "warning": "Bad input. Wrong id!",
        "warning_code": "dead_page",
        "discovery_input": {
            "keyword": "office"
        }
    },
    {
        "post_type": null,
        "timestamp": "2026-02-17T15:26:18.757Z",
        "input": {
            "url": "https://www.pinterest.com/pin/4471026676503806548",
            "discovery_input": {
                "keyword": "office"
            }
        },
        "warning": "Bad input. Page does not exist.",
        "warning_code": "dead_page",
        "discovery_input": {
            "keyword": "office"
        }
    },
    {
        "url": "https://www.pinterest.com/pin/929782285570058239",
        "post_id": "929782285570058239",
        "title": "Essential Tips for Designing a Functional Small Office Space: Maximize Efficiency",
        "content": "17 Smart Tips for Designing a Productive Small Office Space",
        "date_posted": "2026-02-06T15:00:47.000Z",
        "user_name": "wellnesswink",
        "user_url": "https://www.pinterest.com/wellnesswink",
        "user_id": "929782422978147260",
        "followers": 232,
        "likes": 0,
        "categories": [
            "Explore",
            "Home Decor"
        ],
        "attached_files": [
            "https://i.pinimg.com/originals/c8/c0/d5/c8c0d5fb45352e40535db4510049a142.jpg"
        ],
        "image_video_url": "https://i.pinimg.com/originals/c8/c0/d5/c8c0d5fb45352e40535db4510049a142.jpg",
        "video_length": 0,
        "post_type": "image",
        "comments_num": 0,
        "discovery_input": {
            "keyword": "office"
        },
        "timestamp": "2026-02-17T15:26:19.502Z",
        "input": {
            "url": "https://www.pinterest.com/pin/929782285570058239",
            "discovery_input": {
                "keyword": "office"
            }
        }
    },
    {
        "url": "https://www.pinterest.com/pin/889812838892568569",
        "post_id": "889812838892568569",
        "title": "20 Modern Masculine Home Office Design Ideas for Men",
        "content": "Explore 25 chic home office decor ideas that blend style and functionality. Create a workspace you love and boost your productivity effortlessly!",
        "date_posted": "2026-01-27T07:11:38.000Z",
        "user_name": "artfullhouses",
        "user_url": "https://www.pinterest.com/artfullhouses",
        "user_id": "889812976285233957",
        "followers": 10,
        "likes": 0,
        "categories": [
            "Explore",
            "Home Decor"
        ],
        "attached_files": [
            "https://i.pinimg.com/originals/f1/cb/f7/f1cbf7b127db2bef2306ba19ffcc0646.png"
        ],
        "image_video_url": "https://i.pinimg.com/originals/f1/cb/f7/f1cbf7b127db2bef2306ba19ffcc0646.png",
        "video_length": 0,
        "hashtags": [
            "Mens Desk Decor",
            "Chic Home Office Decor",
            "Mens Desk",
            "Home Office Ideas For Men",
            "Office Ideas For Men",
            "Masculine Home Office Ideas",
            "Masculine Home Office",
            "Masculine Home",
            "Chic Home Office"
        ],
        "post_type": "image",
        "comments_num": 0,
        "discovery_input": {
            "keyword": "office"
        },
        "timestamp": "2026-02-17T15:26:20.069Z",
        "input": {
            "url": "https://www.pinterest.com/pin/889812838892568569",
            "discovery_input": {
                "keyword": "office"
            }
        }
    },

```

The Scraper API collects far more data than our Playwright scraper. Our API [crawls](/blog/how-tos/web-crawling-with-python) Pinterest for your `keyword`. It then scrapes every individual pin it finds.

Convenience is not our only benefit from this approach. Our Pinterest Scraper API extracts your data at an extremely low cost. Our total results file was almost 45,000 lines long and it only cost $0.97 to generate. Every new account also includes 5,000 free records each month, with no credit card required.

Hiring someone to build a scraper this good costs several hundred dollars. You would also wait days for your data. With our Scraper API, you get your data within minutes. It costs just a fraction as much.

## <a></a>Conclusion

Extracting data from Pinterest doesn’t have to be difficult. You can build your own scraper with [Playwright](/blog/how-tos/playwright-web-scraping). You can also use a fully automated solution like our Pinterest Scraper. The right approach depends on your needs.

[Bright Data’s Scraper API](/products/web-scraper) removes the hassle of headless browsers and proxies. It handles CAPTCHAs for you. You get structured data without the maintenance work.

✅ **Faster results** – Get data in minutes, not hours.
✅ **Cost-efficient** – Pay only for what you extract.
✅ **No maintenance** – Avoid dealing with blocked requests.

Try our How to scrape pinterest and get 5K records/month for free

Start free trial







## Frequently Asked Questions

### Can you scrape Pinterest without a headless browser?

Not for pin data. Pinterest renders its pin grid in the browser. The HTML does contain JSON blobs such as \_\_PWS\_DATA\_\_, but they hold app config and routes. You need a real browser, or a scraper API that runs one for you.

### Which selector finds pins on a Pinterest search page?

Each pin sits in a div with the attribute data-test-id=”pinWrapper”. Inside it, the anchor holds the pin URL and the aria-label title. The img tag inside that anchor holds the thumbnail URL.

### Why does Pinterest block my headless browser?

Default headless browsers announce themselves through the user agent. Setting a current Chrome user agent avoids the most basic checks. At higher volume you also need rotating proxies to avoid rate limits.

### Is scraping Pinterest legal?

Scraping publicly available data is generally permitted in many jurisdictions. Personal data and copyrighted images carry extra obligations under laws such as GDPR. Check Pinterest’s terms and take legal advice for your own use case.

### How much does the Pinterest Scraper API cost?

Every new Bright Data account includes 5,000 free records each month. Beyond that you pay per record, and you only pay for successful results. The run in this guide produced almost 45,000 lines for $0.97.



Contact usStart free trial

No credit card required











 [ ](https://www.linkedin.com/in/jacob-nulty-682803187/)

Jake Nulty

 Technical Writer



  6 years experience



Jacob Nulty is a Detroit-based software developer and technical writer exploring AI and human philosophy, with experience in Python, Rust, and blockchain.



Expertise

  Data Structures   Python   Rust



 [ View all articles ](https://brightdata.com/blog/authors/jake-nulty)











 Table of Contents







Dedicated Scraper APIs &amp; No-Code Scrapers

Over 1000 scrapers for all popular domains. Simplify your web scraping.

[See pricing](/pricing/web-scraper "See pricing")

Just want data? Skip scraping.

Hundreds of ready-to-use datasets from all popular domains.

[See pricing](/pricing/datasets "See pricing")







 [ ](https://news.ycombinator.com/submitlink?t=How+to+Scrape+Pinterest+in+2026&u=https://brightdata.com/blog/web-data/how-to-scrape-pinterest) [ ](https://www.linkedin.com/shareArticle?mini=true&title=How+to+Scrape+Pinterest+in+2026&url=https://brightdata.com/blog/web-data/how-to-scrape-pinterest) [ ](http://www.reddit.com/submit?title=How+to+Scrape+Pinterest+in+2026&url=https://brightdata.com/blog/web-data/how-to-scrape-pinterest)







##  You might also be interested in

 [ ](https://brightdata.com/blog/ai/openhuman-with-bright-data "Production-Ready Web Access in OpenHuman Through the Bright Data CLI")

 [AI





Antonello Zanini

Technical Writer





### Production-Ready Web Access in OpenHuman Through the Bright Data CLI

Integrate Bright Data CLI with OpenHuman to enable production-ready web access and data collection for AI agents.



 09-Sep-2026

 12 min read

 ](https://brightdata.com/blog/ai/openhuman-with-bright-data)

 [ ](https://brightdata.com/blog/ai/minimax-m3-with-bright-data "Giving self-hosted MiniMax M3 agents live web access with Bright Data")

 [AI





Satyam Tripathi

Technical Writer





### Giving self-hosted MiniMax M3 agents live web access with Bright Data

Self-hosted MiniMax M3 agents get live web access using Bright Data’s search and scraping tools. Bypass blocks and CAPTCHAs.



 09-Sep-2026

 54 min read

 ](https://brightdata.com/blog/ai/minimax-m3-with-bright-data)

 [ ](https://brightdata.com/blog/web-data/multimodal-web-scraping-with-minimax "Multimodal Web Scraping with MiniMax")

 [Web Data





Antonello Zanini

Technical Writer





### Multimodal Web Scraping with MiniMax

Pair Bright Data Web Unlocker with MiniMax M3 vision to extract structured data from images and web page screenshots.



 09-Sep-2026

 4 min read

 ](https://brightdata.com/blog/web-data/multimodal-web-scraping-with-minimax)
