幾個月前,我們其中一位工程師在週末寫好了一支 Python 腳本,拿給我看。它原本是要替一個市場研究專案,從 Pinterest 抓取產品靈感圖片。結果他一跑,抓到的只有……16 個 pin。明明那個 board 裡有超過 2,000 個。她盯著螢幕看了一會兒,又看看我,然後說:「我覺得 Pinterest 在嘲笑我。」
這種情況並不罕見。這幾乎是我看過最多開發者在用 Python 抓 Pinterest 時遇到的挫折。你打開 requests 和 BeautifulSoup,丟一個 Pinterest URL 進去,結果只拿回零星幾筆資料,甚至只是一個空白的 HTML 骨架。原因很簡單:Pinterest 是完全由 JavaScript 渲染的單頁應用程式,單純的 HTTP 請求根本看不到真正內容。在這篇指南裡,我會帶你了解為什麼會這樣、哪些方法真的有效(Playwright、攔截內部 API,以及像 這類免程式工具),並提供逐步程式碼,教你抓取 pins、boards、使用者檔案、無限捲動內容,以及高解析度圖片。不管你是想打造可上線的爬蟲,還是只是想快速抓資料,這篇文章都能幫上忙。
什麼是 Pinterest 爬蟲?
Pinterest 爬蟲是透過程式化方式從 Pinterest 擷取資料的流程,例如 pin 圖片、標題、描述、board 名稱、粉絲數與 URL。你不需要一張張手動瀏覽與儲存 pins,而是用程式(或工具)從搜尋結果、boards 或使用者檔案中大規模收集結構化資料。
截至 2025 年底,Pinterest 平台上已有,每月活躍用戶達,是網路上最豐富的視覺資料來源之一。對企業來說,這些資料非常有價值——不管你是在追蹤產品趨勢、比較競品內容,還是建立網紅合作名單。
為什麼要用 Python 抓 Pinterest?
Pinterest 早就不只是婚禮籌備用的靈感牆了。它其實是一個很有價值的商業情報平台——曾因品牌 Pins 買過東西,而,代表使用者有明確意圖,但未必已有品牌偏好。這對發現新機會來說非常重要,也解釋了為什麼這麼多團隊都想拿到結構化的 Pinterest 資料。
以下是不同團隊可能會需要的資料:
| 團隊 | 需要的資料 | 商業價值 |
|---|---|---|
| 電商營運 | 商品圖片、價格、流行風格 | 競爭性定價、依趨勢調整庫存 |
| 行銷 | Board 表現、pin 互動、競品內容 | 內容策略、活動基準比較 |
| 業務 / 開發名單 | 創作者檔案、粉絲數、聯絡資訊 | 網紅開發、合作對象鎖定 |
| 房地產 | 居家佈置 pins、裝潢趨勢、空間配置 | 房源攝影、佈置建議 |
| 內容創作者 | 熱門主題、流行格式、季節性題材 | 內容行事曆、視覺風格研究 |
更關鍵的是:Pinterest 官方 API 的限制很多。你需要商業帳號、審核(甚至包含應用程式的影片示範),而且只能存取你自己的帳號資料。如果你想瀏覽公開 boards、搜尋結果或競品檔案,爬蟲才是實際可行的替代方案。這也是為什麼很多團隊會選擇 Python——或者在想省掉設定時,直接改用像 Thunderbit 這樣的免程式工具。
為什麼只用 BeautifulSoup 會在 Pinterest 上失敗(以及真正有效的方法)
如果你曾經用 requests + BeautifulSoup 抓 Pinterest,卻只拿到 16 筆資料或空白頁面,那不是你的錯覺。Pinterest 是用 React 打造的,所有內容都透過 JavaScript 動態渲染。當你用一般 HTTP 請求抓 Pinterest URL 時,伺服器只會回傳最小化的 HTML 骨架——幾個 <link>、<script> 標籤,以及 React 要掛載應用程式的空白 <div>。所有 pin 卡片、圖片、標題與網格排版,都是瀏覽器執行 JavaScript 後才注入的。
沒有 JavaScript 執行,就沒有 pins。
那到底什麼方法有效?以下是幾種主要方案的比較:
| 方法 | 支援 JavaScript? | 能取得完整資料? | 複雜度 | 適合用途 |
|---|---|---|---|---|
requests + BeautifulSoup | 否 | 約 0–16 筆 | 低 | 不適合 Pinterest |
| Selenium / Playwright | 是 | 是,需處理捲動 | 中 | 完整控制、Python 流程 |
| 攔截 Pinterest 內部 API | 是 | 是,分頁 JSON | 高 | 最大化資料量,不需瀏覽器 |
| 第三方 Scraper API | 是 | 依服務而定 | 低 | 不想自建基礎架構的規模化需求 |
| 免程式工具(Thunderbit) | 是 | AI 結構化 | 很低 | 非技術使用者、快速取得結果 |
這篇教學我會推薦用 Playwright 作為 Python 方案。它可以渲染 JavaScript、支援模擬捲動、維護良好(GitHub 上有,且在職缺中的成長率達),而且在效能測試上比 Selenium 快上。如果你想走免程式路線,我也會一起介紹。
Pinterest 官方 API vs. Python 爬蟲 vs. 免程式工具:該選哪條路?
在你開始寫程式前,先問自己:真的需要自己寫嗎?以下是決策參考:
| 評估項目 | Pinterest API | Python 爬蟲 | Thunderbit(免程式) |
|---|---|---|---|
| 需要審核 | 商業帳號 + 影片示範 | 不需要 | 不需要 |
| 可存取公開 pins/boards | 有限(僅自己的資料) | 完整 | 完整 |
| 可下載高解析度圖片 | 依情況而定 | 可以,透過 URL 解析 | 可以,透過圖片擷取 |
| 支援無限捲動 | 不適用 | 可以,需寫程式 | 自動處理 |
| 維護成本 | 低 | 高(selector 容易失效) | 幾乎沒有(AI 自動調整) |
| 匯出到 Sheets/Airtable | 手動 | 自行撰寫程式 | 內建支援 |
| 設定時間 | 幾小時到幾天 | 30–60 分鐘 | 2 分鐘 |
如果你是行銷、電商營運,或任何只想把 Pinterest 資料放進試算表、又不想寫或維護 Python 腳本的人, 會是最快的路。你只要打開任何 Pinterest 頁面,點選「AI Suggest Fields」,再按「Scrape」,就能直接匯出到 Google Sheets、Excel、Airtable 或 Notion。它的子頁面擷取功能甚至可以自動追蹤單一 pin 的連結來補齊資料。我看過完全沒寫過程式的人,在三分鐘內把 500 多個 pins 匯入 Google Sheet。
如果你想要完全掌控流程、想把爬蟲整合進 Python pipeline,或單純喜歡自己動手打造工具,那就繼續看下去。
建立 Pinterest 爬蟲的 Python 環境
- 難度: 中等
- 所需時間: 約 30–60 分鐘(含撰寫與測試)
- 你需要準備: Python 3.9+、Chrome 瀏覽器(用於測試)、終端機 / 命令列存取權限
安裝 Playwright 與相依套件
先建立專案資料夾並設定虛擬環境:
1mkdir pinterest-scraper
2cd pinterest-scraper
3python -m venv venv
4source venv/bin/activate # On Windows: venv\Scripts\activate
安裝 Playwright 並下載 Chromium 瀏覽器執行檔:
1pip install playwright
2playwright install chromium
你也會用到 Python 內建的 json、os 與 csv 模組來匯出資料,這些不需要額外安裝。
專案資料夾結構
我建議一開始就把架構整理好:
1pinterest-scraper/
2├── scraper.py
3├── config.py
4├── output/
5│ ├── pins.json
6│ └── pins.csv
7└── images/
8 ├── board-name-1/
9 └── board-name-2/
在 config.py 裡設定你的 user agent 字串。Pinterest 會阻擋預設的無頭瀏覽器識別字串,所以要用更接近真實瀏覽器的版本:
1USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
步驟 1:建立 Pinterest 搜尋 URL
把查詢字串塞進網址範本中:
1query = "mid century modern furniture"
2url = f"https://www.pinterest.com/search/pins/?q={query.replace(' ', '%20')}&rs=typed"
你可以把它參數化,套用到任何搜尋詞。rs=typed 這個參數會告訴 Pinterest,這個查詢是手動輸入的(不是建議詞),有時會影響結果相關性。
步驟 2:啟動無頭瀏覽器並載入頁面
下面是核心的 Playwright 設定。注意自訂 user agent——如果沒有它,Pinterest 很可能會封鎖你,或直接顯示登入牆。
1import asyncio
2from playwright.async_api import async_playwright
3from config import USER_AGENT
4async def scrape_search(query, max_pins=100):
5 url = f"https://www.pinterest.com/search/pins/?q={query.replace(' ', '%20')}&rs=typed"
6 async with async_playwright() as p:
7 browser = await p.chromium.launch(headless=True)
8 page = await browser.new_page(
9 user_agent=USER_AGENT,
10 viewport={"width": 1920, "height": 1080}
11 )
12 await page.goto(url)
13 await asyncio.sleep(3) # 等待 JavaScript 渲染初始 pins
執行完後,頁面應該會載入第一批 pins,通常約 25–50 個。
步驟 3:從頁面擷取 pin 資料
Pinterest 會把每個 pin 包在 div[data-test-id='pinWrapper'] 裡。裡面會有一個連結(<a>),包含 pin 的 URL 和標題(透過 aria-label),以及一個 <img>,裡面有縮圖 URL。
1 results = []
2 pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
3 for pin in pins:
4 link = await pin.query_selector("a")
5 if not link:
6 continue
7 title = await link.get_attribute("aria-label") or ""
8 href = await link.get_attribute("href") or ""
9 img = await pin.query_selector("img")
10 src = await img.get_attribute("src") if img else ""
11 results.append({
12 "title": title,
13 "url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
14 "image_url": src
15 })
此時 results 只包含初始畫面上看得到的 pins。若要取得更多,就需要捲動——這也是最重要的部分。
步驟 4:將結果儲存成 JSON 或 CSV
擷取完成後,把資料寫入檔案,方便後續使用:
1import json
2import csv
3def save_json(data, filepath="output/pins.json"):
4 with open(filepath, "w", encoding="utf-8") as f:
5 json.dump(data, f, ensure_ascii=False, indent=2)
6def save_csv(data, filepath="output/pins.csv"):
7 if not data:
8 return
9 with open(filepath, "w", newline="", encoding="utf-8-sig") as f:
10 writer = csv.DictWriter(f, fieldnames=data[0].keys())
11 writer.writeheader()
12 writer.writerows(data)
如果你打算用 Excel 開啟 CSV,建議使用 utf-8-sig 編碼,這樣可以避免亂碼。
擷取整個 Pinterest Board 與使用者檔案
這是現有教學裡很大的缺口。我幾乎找不到任何競品文章會深入講 board 或 profile 的擷取,但這卻是論壇裡最常被問到的功能之一。大家想下載某個 board 的全部 pins、把圖片依 board 分資料夾,還想抓取使用者檔案層級的資料,例如粉絲數與 board 清單。
從 Board URL 擷取所有 Pins
Board URL 通常長這樣:https://www.pinterest.com/{username}/{board-name}/。DOM 結構和搜尋結果類似——pins 一樣包在 div[data-test-id='pinWrapper'] 裡——但你需要捲動才能把它們全部載入。
1async def scrape_board(board_url, max_pins=500):
2 async with async_playwright() as p:
3 browser = await p.chromium.launch(headless=True)
4 page = await browser.new_page(user_agent=USER_AGENT, viewport={"width": 1920, "height": 1080})
5 await page.goto(board_url)
6 await asyncio.sleep(3)
7 seen_ids = set()
8 all_pins = []
9 for scroll_round in range(100): # 安全上限
10 pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
11 new_count = 0
12 for pin in pins:
13 link = await pin.query_selector("a")
14 if not link:
15 continue
16 href = await link.get_attribute("href") or ""
17 if href in seen_ids:
18 continue
19 seen_ids.add(href)
20 new_count += 1
21 title = await link.get_attribute("aria-label") or ""
22 img = await link.query_selector("img")
23 src = await img.get_attribute("src") if img else ""
24 all_pins.append({
25 "title": title,
26 "url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
27 "image_url": src
28 })
29 print(f"Scroll {scroll_round + 1}: 已收集 {len(all_pins)} 個唯一 pins")
30 if new_count == 0 or len(all_pins) >= max_pins:
31 break
32 prev_height = await page.evaluate("document.body.scrollHeight")
33 await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
34 await asyncio.sleep(2.5)
35 curr_height = await page.evaluate("document.body.scrollHeight")
36 if curr_height == prev_height:
37 break # 沒有更多內容
38 await browser.close()
39 return all_pins
要注意的一點是:board 頁面有時會出現一個「More Ideas」分頁,把已儲存的 pins 和演算法推薦內容分開。如果你只想抓使用者實際儲存的 pins,那麼當你碰到那個分隔區塊時,就可以停止捲動。
擷取使用者檔案:boards、粉絲數與 pins
Profile URL 長這樣:https://www.pinterest.com/{username}/。從 profile 頁面可以擷取:
- 粉絲 / 追蹤中數量: 找
div[data-test-id='follower-count'] - Board 清單: 每個 board 都是一張卡片,連到
/{username}/{board-name}/ - 總 pins 數: 有時會顯示在 profile 標頭中
1async def scrape_profile(username):
2 url = f"https://www.pinterest.com/{username}/"
3 async with async_playwright() as p:
4 browser = await p.chromium.launch(headless=True)
5 page = await browser.new_page(user_agent=USER_AGENT, viewport={"width": 1920, "height": 1080})
6 await page.goto(url)
7 await asyncio.sleep(3)
8 # 擷取粉絲數
9 follower_el = await page.query_selector("div[data-test-id='follower-count']")
10 followers = await follower_el.inner_text() if follower_el else "N/A"
11 # 擷取 board 連結
12 board_links = await page.query_selector_all("a[href*='/" + username + "/']")
13 boards = []
14 for bl in board_links:
15 href = await bl.get_attribute("href") or ""
16 name = await bl.get_attribute("aria-label") or href.split("/")[-2]
17 if href.count("/") >= 3 and href != f"/{username}/":
18 boards.append({"name": name, "url": f"https://www.pinterest.com{href}"})
19 await browser.close()
20 return {"username": username, "followers": followers, "boards": boards}
如果你想抓取某個 profile 底下所有 board 的 pins,可以把 board 清單迴圈跑一遍,對每個 board 呼叫 scrape_board()。你也可以自動把下載的圖片整理到各自的 board 資料夾中。
建立可上線使用的無限捲動處理器
這個部分決定了一支腳本是玩具還是真正可用的爬蟲。最常見的痛點——我在至少十幾個論壇討論串裡都看過——就是爬蟲只抓到 16–25 筆資料,原因不是它不會跑,而是它沒有捲得夠遠,或只是寫了固定次數的 for i in range(5): scroll() 然後祈禱它成功。
這種寫法不可靠。Pinterest 會在捲動事件觸發時,以大約 25 個 pin 為一批載入新內容。你捲五次,可能拿到 125 個 pins,也可能因為網路較慢只拿到 75 個,甚至只有 150 個,視批次大小而定。你需要更聰明的做法。
滾動直到沒有新內容的模式
以下是一個更穩健的捲動函式,它會追蹤唯一的 pin ID、使用可調整的 timeout、加入重試邏輯,並顯示進度:
1import time
2import random
3async def scroll_and_collect(page, max_pins=1000, max_scrolls=200, scroll_pause=2.5):
4 seen_ids = set()
5 all_pins = []
6 no_new_count = 0
7 for i in range(max_scrolls):
8 pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
9 new_this_round = 0
10 for pin in pins:
11 link = await pin.query_selector("a")
12 if not link:
13 continue
14 href = await link.get_attribute("href") or ""
15 if href in seen_ids:
16 continue
17 seen_ids.add(href)
18 new_this_round += 1
19 title = await link.get_attribute("aria-label") or ""
20 img = await link.query_selector("img")
21 src = await img.get_attribute("src") if img else ""
22 all_pins.append({
23 "title": title,
24 "url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
25 "image_url": src
26 })
27 print(f" 第 {i+1} 次捲動:{new_this_round} 個新 pins|共 {len(all_pins)} 個唯一 pins")
28 if len(all_pins) >= max_pins:
29 print(f" 已達到 max_pins 上限({max_pins})。停止。")
30 break
31 if new_this_round == 0:
32 no_new_count += 1
33 if no_new_count >= 3:
34 print(" 連續 3 次捲動都沒有新 pins。內容已到底。")
35 break
36 else:
37 no_new_count = 0
38 prev_height = await page.evaluate("document.body.scrollHeight")
39 await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
40 await asyncio.sleep(scroll_pause + random.uniform(0.5, 1.5))
41 curr_height = await page.evaluate("document.body.scrollHeight")
42 if curr_height == prev_height and new_this_round == 0:
43 print(" 頁面高度未變,且沒有新 pins。很可能已經到底。")
44 break
45 return all_pins
為什麼這個設計有效:
- 依 href 去重: 每個 pin 的 URL 都是唯一的,所以我們把它當作 ID 使用。這可以避免在捲動期間 DOM 重新渲染時,重複計算同一個 pin。
- 三次無新增就停止: 如果連續三次捲動都沒有新資料,就停止。這能處理頁面還在載入、但其實已經沒有新內容的情況。
- 加入隨機抖動: 在每次捲動之間加入 0.5–1.5 秒的隨機延遲,行為會更接近真人,也能降低觸發反爬機制的機率。
- 最大捲動次數保護: 避免因為程式錯誤而陷入無限迴圈。
處理特殊狀況
- 「More Ideas」中斷: 在 board 頁面裡,Pinterest 有時會插入一個「More Ideas」區塊。如果你只想抓這個 board 真正儲存的 pins,可以偵測到這個元素後停止捲動。
- 長時間操作的限流: 如果你正在捲動一個有上千個 pins 的 board,Pinterest 可能會開始限制回應速度。若你發現捲動有時候會抓不到新資料(但不是連續三次),把
scroll_pause調整到 5 秒以上。
取得 Pinterest 的完整解析度圖片(不是縮圖)
這點最容易讓人抓狂。你抓了一堆 pins,把圖片下載下來,結果全都是 236px 的小縮圖。論壇使用者常把它形容成「品質很糟,尺寸太小」。解法就是了解 Pinterest 的圖片 URL 結構。
了解 Pinterest 圖片 URL 路徑
Pinterest 的圖片都由 https://i.pinimg.com/{size}/{hash}.jpg 提供服務。{size} 這個區段決定解析度:
| 尺寸路徑 | 圖片尺寸 | 用途 |
|---|---|---|
/236x/ | 寬 236px | 預設網格檢視(你最常拿到的版本) |
/474x/ | 寬 474px | 中等解析度 |
/736x/ | 寬 736px | pin 詳細頁 / 展開檢視 |
/originals/ | 原始上傳尺寸 | 完整解析度 |
工具函式:將任何 Pinterest 圖片 URL 升級到高解析度
下面這個函式會把任何 Pinterest 圖片 URL 改寫成可用的最高畫質,並附帶 fallback 邏輯:
1import requests as req
2def upgrade_image_url(url, preferred_size="originals"):
3 """將 Pinterest 圖片 URL 改寫為最高可用解析度。"""
4 sizes = ["originals", "736x", "474x", "236x"]
5 if preferred_size not in sizes:
6 preferred_size = "originals"
7 for size in sizes[sizes.index(preferred_size):]:
8 upgraded = url
9 for s in sizes:
10 upgraded = upgraded.replace(f"/{s}/", f"/{size}/")
11 try:
12 resp = req.head(upgraded, timeout=5, allow_redirects=True)
13 if resp.status_code == 200:
14 return upgraded
15 except Exception:
16 continue
17 return url # 如果都失敗,就回傳原始網址
重要提醒(截至 2025 年): /originals/ 路徑越來越常回傳 HTTP 403 Forbidden。gallery-dl 的也證實了這個行為在 2025 年中期依然存在。實務上最可靠的最高解析度通常是 /736x/。我的函式會先嘗試 /originals/,失敗後自動改用 /736x/。
將圖片下載到有整理的資料夾
1import os
2import time
3def download_images(pins, folder="images/default", delay=1.5):
4 os.makedirs(folder, exist_ok=True)
5 for i, pin in enumerate(pins):
6 img_url = upgrade_image_url(pin.get("image_url", ""), preferred_size="736x")
7 if not img_url:
8 continue
9 filename = f"pin_{i+1}.jpg"
10 filepath = os.path.join(folder, filename)
11 try:
12 resp = req.get(img_url, timeout=15)
13 if resp.status_code == 200:
14 with open(filepath, "wb") as f:
15 f.write(resp.content)
16 print(f" 已下載 {filename}({len(resp.content) // 1024} KB)")
17 else:
18 print(f" {filename} 下載失敗:HTTP {resp.status_code}")
19 except Exception as e:
20 print(f" 下載 {filename} 時發生錯誤:{e}")
21 time.sleep(delay + random.uniform(0.3, 0.8))
下載之間記得加上節流延遲。我通常會使用 1.5–2.3 秒,並加上隨機抖動。如果不這樣做,Pinterest 幾百次請求後就可能封鎖你的 IP。
匯出你抓到的 Pinterest 資料
匯出成 CSV 或 JSON
前面我們已經說過基本做法。如果資料量很大(10,000+ 個 pins),可以考慮 JSON Lines 格式——每行一個 JSON 物件——這樣更容易串流與處理:
1def save_jsonl(data, filepath="output/pins.jsonl"):
2 with open(filepath, "w", encoding="utf-8") as f:
3 for item in data:
4 f.write(json.dumps(item, ensure_ascii=False) + "\n")
匯出到 Google Sheets、Airtable 或 Notion
如果你想直接從 Python 把資料送到 Google Sheets,需要使用 gspread 套件和 Google Cloud service account。Airtable 可以用 pyairtable,Notion 則是 notion-client。每一種都需要 API key 設定,而且會讓整條流程變得更複雜。
或者——雖然我有點偏心,但這真的是最快的方法——你也可以用 直接抓 Pinterest,然後一鍵匯出到這些目的地。沒有 API keys,沒有 service account,也不用額外寫程式。 可以原生處理匯出。
如何避免在抓 Pinterest 時被封鎖
ScrapeOps 將 Pinterest 的反機器人系統評為——不算簡單,但也不是最難對付的目標。它會使用瀏覽器指紋辨識、行為分析與基於 IP 的限流。以下做法比較有效:
- 輪換 user agent: 準備一組真實 Chrome user agent 字串,每次 session 隨機選一個。
- 加入隨機延遲: 捲動與請求之間加入 2–5 秒的等待,並帶些隨機抖動。如果沒有代理,則建議拉長到 10–15 秒。
- 使用合理的視窗大小: 設定
viewport={"width": 1920, "height": 1080},不要用太小或奇怪的尺寸。 - 大規模作業請考慮代理: 如果你要抓幾千個 pins,建議使用住宅代理輪換。沒有代理的話,幾百次請求後就可能被封。
- 注意
robots.txt: Pinterest 的robots.txt封鎖了大多數自動爬蟲,且有。做合規評估時要留意。 - 避免登入後爬取: 盡量只抓登入狀態下可直接看到的公開內容。登入後抓取會帶來法律與技術風險。
如果你走免程式路線,Thunderbit 的 AI 引擎會自動處理反機器人與 CAPTCHA 挑戰,讓你少維護一大堆東西。
Pinterest 爬蟲的法律與倫理考量
這部分我會簡短帶過,因為不是本文重點,但它很重要。
Pinterest 的服務條款(第 2a 條)指出,你同意不會以未經授權的方式「scrape、collect、search、copy 或以其他方式存取 Pinterest 的資料或內容」,例如使用自動化方式(且未事先取得我們明確許可)。儘管如此,法院通常認為,抓取公開可得資料並不違反 Computer Fraud and Abuse Act——可參考 以及 Meta v. Bright Data(2024 年 1 月),該案中法院裁定,在登出狀態下抓取公開可見資料是合法的。
幾個基本原則:
- 只抓取登出狀態下可公開瀏覽的內容
- 不要把抓來的資料用於垃圾訊息或冒充使用者
- 尊重圖片著作權——盡可能只擷取中繼資料,未經許可不要商業性重發受著作權保護的圖片
- 如果你打算把資料用於商業用途,請先諮詢律師
如果你想更深入了解法律面,請參考我們的。
結語:你學到了什麼,以及下一步該做什麼
現在你已經知道為什麼靜態爬取在 Pinterest 上會失敗(它是 React SPA——沒有 JavaScript,就沒有資料)、如何用 Playwright 抓搜尋結果、boards 和使用者檔案、如何建立一個能撐住實戰的無限捲動處理器,不會只抓到 16 個 pin 就停下來,以及如何拿到高解析度圖片,而不是小縮圖。
重點快速回顧:
requests+ BeautifulSoup 在 Pinterest 上行不通,別浪費時間。- Playwright 是這項工作的最佳 Python 工具——速度快、支援完善,且能原生處理 JavaScript 渲染。
- 無限捲動 需要的是基於去重的捲動迴圈,而不是固定次數。
- 高解析度圖片 需要改寫 URL 路徑——請優先使用
/736x/(因為/originals/經常回傳 403)。 - Board 與 profile 擷取 在現有教學中比較少被談到,但只要 selector 正確,其實不難。
- 如果你不想寫程式,或只想要快, 讓你 2 下點擊就能抓 Pinterest,並匯出到 Google Sheets、Excel、Airtable 或 Notion——完全不需要 Python。你可以透過 免費試用。
如果你正在打造 Python pipeline,本指南中的程式碼能提供穩固基礎。如果你只是需要資料,Thunderbit 會是更快的捷徑。不管哪種方式,你都不必再卡在只抓到 16 個 pin、對著空白螢幕發呆了。
想了解更多關於爬蟲與資料擷取的內容,歡迎參考我們的指南:、、以及。你也可以查看 ,或到 看教學影片。
常見問題
1. 可以只用 BeautifulSoup 抓 Pinterest 嗎?
單獨使用效果並不好。Pinterest 的所有內容都是透過 JavaScript 渲染,所以 requests + BeautifulSoup 只會看到空的 HTML 骨架。你需要先用 Playwright 或 Selenium 這類無頭瀏覽器把頁面渲染出來,或者直接用像 Thunderbit 這種會自動處理 JavaScript 渲染的免程式工具。
2. 一次 session 可以從 Pinterest 抓多少個 pins?
這取決於你的捲動邏輯與反機器人處理方式。使用本文的可上線無限捲動處理器(去重、timeout、重試邏輯)時,每個 board 或搜尋字詞通常可以穩定抓到數百到數千個 pins。若 board 很大,捲動與收集可能需要幾分鐘。
3. 為什麼我抓到的 Pinterest 圖片都很小?
預設情況下,Pinterest 在網格視圖中會提供 /236x/ 縮圖。若要更高解析度,請把圖片 URL 路徑改成 /736x/ 或 /originals/。不過截至 2025 年,/originals/ 越來越常回傳 403,因此 /736x/ 才是比較可靠的最高版本。
4. 抓 Pinterest 合法嗎?
根據近期法院判決(例如 hiQ v. LinkedIn、Meta v. Bright Data),抓取公開可得資料通常是被接受的,但 Pinterest 的服務條款禁止未經授權的自動化存取。請僅限公開內容,不要把資料用於垃圾訊息,尊重著作權,若是商業用途則請先諮詢法律專業人士。
5. 抓 Pinterest 最好的免程式替代方案是什麼?
可以在 2 次點擊內擷取 Pinterest pin 資料——包含標題、圖片、URL、描述——並內建匯出到 Google Sheets、Excel、Airtable 或 Notion。它會自動處理 JavaScript 渲染、無限捲動與反機器人挑戰,所以你完全不需要寫或維護任何程式。
了解更多