幾個月前,我們其中一位工程師在週末寫好了一支 Python 腳本,拿給我看。它原本是要替一個市場研究專案,從 Pinterest 抓取產品靈感圖片。結果他一跑,抓到的只有……16 個 pin。明明那個 board 裡有超過 2,000 個。她盯著螢幕看了一會兒,又看看我,然後說:「我覺得 Pinterest 在嘲笑我。」
這種情況並不罕見。這幾乎是我看過最多開發者在用 Python 抓 Pinterest 時遇到的挫折。你打開 requests 和 BeautifulSoup,丟一個 Pinterest URL 進去,結果只拿回零星幾筆資料,甚至只是一個空白的 HTML 骨架。原因很簡單:Pinterest 是完全由 JavaScript 渲染的單頁應用程式,單純的 HTTP 請求根本看不到真正內容。在這篇指南裡,我會帶你了解為什麼會這樣、哪些方法真的有效(Playwright、攔截內部 API,以及像 Thunderbit 這類免程式工具),並提供逐步程式碼,教你抓取 pins、boards、使用者檔案、無限捲動內容,以及高解析度圖片。不管你是想打造可上線的爬蟲,還是只是想快速抓資料,這篇文章都能幫上忙。
什麼是 Pinterest 爬蟲?
Pinterest 爬蟲是透過程式化方式從 Pinterest 擷取資料的流程,例如 pin 圖片、標題、描述、board 名稱、粉絲數與 URL。你不需要一張張手動瀏覽與儲存 pins,而是用程式(或工具)從搜尋結果、boards 或使用者檔案中大規模收集結構化資料。
截至 2025 年底,Pinterest 平台上已有超過 2400 億個 Pins,每月活躍用戶達6.19 億,是網路上最豐富的視覺資料來源之一。對企業來說,這些資料非常有價值——不管你是在追蹤產品趨勢、比較競品內容,還是建立網紅合作名單。
為什麼要用 Python 抓 Pinterest?
Pinterest 早就不只是婚禮籌備用的靈感牆了。它其實是一個很有價值的商業情報平台——85% 的每週 Pinterest 使用者曾因品牌 Pins 買過東西,而96–97% 的熱門搜尋都不是品牌詞,代表使用者有明確意圖,但未必已有品牌偏好。這對發現新機會來說非常重要,也解釋了為什麼這麼多團隊都想拿到結構化的 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 上有78,600+ 顆星,且在職缺中的成長率達年增 180%),而且在效能測試上比 Selenium 快上35–45%。如果你想走免程式路線,我也會一起介紹。
Pinterest 官方 API vs. Python 爬蟲 vs. 免程式工具:該選哪條路?
在你開始寫程式前,先問自己:真的需要自己寫嗎?以下是決策參考:
| 評估項目 | Pinterest API | Python 爬蟲 | Thunderbit(免程式) |
|---|---|---|---|
| 需要審核 | 商業帳號 + 影片示範 | 不需要 | 不需要 |
| 可存取公開 pins/boards | 有限(僅自己的資料) | 完整 | 完整 |
| 可下載高解析度圖片 | 依情況而定 | 可以,透過 URL 解析 | 可以,透過圖片擷取 |
| 支援無限捲動 | 不適用 | 可以,需寫程式 | 自動處理 |
| 維護成本 | 低 | 高(selector 容易失效) | 幾乎沒有(AI 自動調整) |
| 匯出到 Sheets/Airtable | 手動 | 自行撰寫程式 | 內建支援 |
| 設定時間 | 幾小時到幾天 | 30–60 分鐘 | 2 分鐘 |
如果你是行銷、電商營運,或任何只想把 Pinterest 資料放進試算表、又不想寫或維護 Python 腳本的人,Thunderbit 的 AI Web Scraper 會是最快的路。你只要打開任何 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 與相依套件
先建立專案資料夾並設定虛擬環境:
mkdir pinterest-scraper
cd pinterest-scraper
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
安裝 Playwright 並下載 Chromium 瀏覽器執行檔:
pip install playwright
playwright install chromium
你也會用到 Python 內建的 json、os 與 csv 模組來匯出資料,這些不需要額外安裝。
專案資料夾結構
我建議一開始就把架構整理好:
pinterest-scraper/
├── scraper.py
├── config.py
├── output/
│ ├── pins.json
│ └── pins.csv
└── images/
├── board-name-1/
└── board-name-2/
在 config.py 裡設定你的 user agent 字串。Pinterest 會阻擋預設的無頭瀏覽器識別字串,所以要用更接近真實瀏覽器的版本:
USER_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
把查詢字串塞進網址範本中:
query = "mid century modern furniture"
url = f"https://www.pinterest.com/search/pins/?q={query.replace(' ', '%20')}&rs=typed"
你可以把它參數化,套用到任何搜尋詞。rs=typed 這個參數會告訴 Pinterest,這個查詢是手動輸入的(不是建議詞),有時會影響結果相關性。
步驟 2:啟動無頭瀏覽器並載入頁面
下面是核心的 Playwright 設定。注意自訂 user agent——如果沒有它,Pinterest 很可能會封鎖你,或直接顯示登入牆。
import asyncio
from playwright.async_api import async_playwright
from config import USER_AGENT
async def scrape_search(query, max_pins=100):
url = f"https://www.pinterest.com/search/pins/?q={query.replace(' ', '%20')}&rs=typed"
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page(
user_agent=USER_AGENT,
viewport={"width": 1920, "height": 1080}
)
await page.goto(url)
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。
results = []
pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
for pin in pins:
link = await pin.query_selector("a")
if not link:
continue
title = await link.get_attribute("aria-label") or ""
href = await link.get_attribute("href") or ""
img = await pin.query_selector("img")
src = await img.get_attribute("src") if img else ""
results.append({
"title": title,
"url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
"image_url": src
})
此時 results 只包含初始畫面上看得到的 pins。若要取得更多,就需要捲動——這也是最重要的部分。
步驟 4:將結果儲存成 JSON 或 CSV
擷取完成後,把資料寫入檔案,方便後續使用:
import json
import csv
def save_json(data, filepath="output/pins.json"):
with open(filepath, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def save_csv(data, filepath="output/pins.csv"):
if not data:
return
with open(filepath, "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
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'] 裡——但你需要捲動才能把它們全部載入。
async def scrape_board(board_url, max_pins=500):
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page(user_agent=USER_AGENT, viewport={"width": 1920, "height": 1080})
await page.goto(board_url)
await asyncio.sleep(3)
seen_ids = set()
all_pins = []
for scroll_round in range(100): # 安全上限
pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
new_count = 0
for pin in pins:
link = await pin.query_selector("a")
if not link:
continue
href = await link.get_attribute("href") or ""
if href in seen_ids:
continue
seen_ids.add(href)
new_count += 1
title = await link.get_attribute("aria-label") or ""
img = await link.query_selector("img")
src = await img.get_attribute("src") if img else ""
all_pins.append({
"title": title,
"url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
"image_url": src
})
print(f"Scroll {scroll_round + 1}: 已收集 {len(all_pins)} 個唯一 pins")
if new_count == 0 or len(all_pins) >= max_pins:
break
prev_height = await page.evaluate("document.body.scrollHeight")
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
await asyncio.sleep(2.5)
curr_height = await page.evaluate("document.body.scrollHeight")
if curr_height == prev_height:
break # 沒有更多內容
await browser.close()
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 標頭中
async def scrape_profile(username):
url = f"https://www.pinterest.com/{username}/"
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page(user_agent=USER_AGENT, viewport={"width": 1920, "height": 1080})
await page.goto(url)
await asyncio.sleep(3)
# 擷取粉絲數
follower_el = await page.query_selector("div[data-test-id='follower-count']")
followers = await follower_el.inner_text() if follower_el else "N/A"
# 擷取 board 連結
board_links = await page.query_selector_all("a[href*='/" + username + "/']")
boards = []
for bl in board_links:
href = await bl.get_attribute("href") or ""
name = await bl.get_attribute("aria-label") or href.split("/")[-2]
if href.count("/") >= 3 and href != f"/{username}/":
boards.append({"name": name, "url": f"https://www.pinterest.com{href}"})
await browser.close()
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、加入重試邏輯,並顯示進度:
import time
import random
async def scroll_and_collect(page, max_pins=1000, max_scrolls=200, scroll_pause=2.5):
seen_ids = set()
all_pins = []
no_new_count = 0
for i in range(max_scrolls):
pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
new_this_round = 0
for pin in pins:
link = await pin.query_selector("a")
if not link:
continue
href = await link.get_attribute("href") or ""
if href in seen_ids:
continue
seen_ids.add(href)
new_this_round += 1
title = await link.get_attribute("aria-label") or ""
img = await link.query_selector("img")
src = await img.get_attribute("src") if img else ""
all_pins.append({
"title": title,
"url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
"image_url": src
})
print(f" 第 {i+1} 次捲動:{new_this_round} 個新 pins|共 {len(all_pins)} 個唯一 pins")
if len(all_pins) >= max_pins:
print(f" 已達到 max_pins 上限({max_pins})。停止。")
break
if new_this_round == 0:
no_new_count += 1
if no_new_count >= 3:
print(" 連續 3 次捲動都沒有新 pins。內容已到底。")
break
else:
no_new_count = 0
prev_height = await page.evaluate("document.body.scrollHeight")
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
await asyncio.sleep(scroll_pause + random.uniform(0.5, 1.5))
curr_height = await page.evaluate("document.body.scrollHeight")
if curr_height == prev_height and new_this_round == 0:
print(" 頁面高度未變,且沒有新 pins。很可能已經到底。")
break
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 邏輯:
import requests as req
def upgrade_image_url(url, preferred_size="originals"):
"""將 Pinterest 圖片 URL 改寫為最高可用解析度。"""
sizes = ["originals", "736x", "474x", "236x"]
if preferred_size not in sizes:
preferred_size = "originals"
for size in sizes[sizes.index(preferred_size):]:
upgraded = url
for s in sizes:
upgraded = upgraded.replace(f"/{s}/", f"/{size}/")
try:
resp = req.head(upgraded, timeout=5, allow_redirects=True)
if resp.status_code == 200:
return upgraded
except Exception:
continue
return url # 如果都失敗,就回傳原始網址
重要提醒(截至 2025 年): /originals/ 路徑越來越常回傳 HTTP 403 Forbidden。gallery-dl 的一個已知問題也證實了這個行為在 2025 年中期依然存在。實務上最可靠的最高解析度通常是 /736x/。我的函式會先嘗試 /originals/,失敗後自動改用 /736x/。
將圖片下載到有整理的資料夾
import os
import time
def download_images(pins, folder="images/default", delay=1.5):
os.makedirs(folder, exist_ok=True)
for i, pin in enumerate(pins):
img_url = upgrade_image_url(pin.get("image_url", ""), preferred_size="736x")
if not img_url:
continue
filename = f"pin_{i+1}.jpg"
filepath = os.path.join(folder, filename)
try:
resp = req.get(img_url, timeout=15)
if resp.status_code == 200:
with open(filepath, "wb") as f:
f.write(resp.content)
print(f" 已下載 {filename}({len(resp.content) // 1024} KB)")
else:
print(f" {filename} 下載失敗:HTTP {resp.status_code}")
except Exception as e:
print(f" 下載 {filename} 時發生錯誤:{e}")
time.sleep(delay + random.uniform(0.3, 0.8))
下載之間記得加上節流延遲。我通常會使用 1.5–2.3 秒,並加上隨機抖動。如果不這樣做,Pinterest 幾百次請求後就可能封鎖你的 IP。
匯出你抓到的 Pinterest 資料
匯出成 CSV 或 JSON
前面我們已經說過基本做法。如果資料量很大(10,000+ 個 pins),可以考慮 JSON Lines 格式——每行一個 JSON 物件——這樣更容易串流與處理:
def save_jsonl(data, filepath="output/pins.jsonl"):
with open(filepath, "w", encoding="utf-8") as f:
for item in data:
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 設定,而且會讓整條流程變得更複雜。
或者——雖然我有點偏心,但這真的是最快的方法——你也可以用 Thunderbit 直接抓 Pinterest,然後一鍵匯出到這些目的地。沒有 API keys,沒有 service account,也不用額外寫程式。Thunderbit Chrome Extension 可以原生處理匯出。
如何避免在抓 Pinterest 時被封鎖
ScrapeOps 將 Pinterest 的反機器人系統評為6/10 的繞過難度——不算簡單,但也不是最難對付的目標。它會使用瀏覽器指紋辨識、行為分析與基於 IP 的限流。以下做法比較有效:
- 輪換 user agent: 準備一組真實 Chrome user agent 字串,每次 session 隨機選一個。
- 加入隨機延遲: 捲動與請求之間加入 2–5 秒的等待,並帶些隨機抖動。如果沒有代理,則建議拉長到 10–15 秒。
- 使用合理的視窗大小: 設定
viewport={"width": 1920, "height": 1080},不要用太小或奇怪的尺寸。 - 大規模作業請考慮代理: 如果你要抓幾千個 pins,建議使用住宅代理輪換。沒有代理的話,幾百次請求後就可能被封。
- 注意
robots.txt: Pinterest 的robots.txt封鎖了大多數自動爬蟲,且有大約 180 條 disallow 規則。做合規評估時要留意。 - 避免登入後爬取: 盡量只抓登入狀態下可直接看到的公開內容。登入後抓取會帶來法律與技術風險。
如果你走免程式路線,Thunderbit 的 AI 引擎會自動處理反機器人與 CAPTCHA 挑戰,讓你少維護一大堆東西。
Pinterest 爬蟲的法律與倫理考量
這部分我會簡短帶過,因為不是本文重點,但它很重要。
Pinterest 的服務條款(第 2a 條)指出,你同意不會以未經授權的方式「scrape、collect、search、copy 或以其他方式存取 Pinterest 的資料或內容」,例如使用自動化方式(且未事先取得我們明確許可)。儘管如此,法院通常認為,抓取公開可得資料並不違反 Computer Fraud and Abuse Act——可參考 hiQ v. LinkedIn 以及 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 正確,其實不難。
- 如果你不想寫程式,或只想要快, Thunderbit 讓你 2 下點擊就能抓 Pinterest,並匯出到 Google Sheets、Excel、Airtable 或 Notion——完全不需要 Python。你可以透過 Chrome Extension 免費試用。
如果你正在打造 Python pipeline,本指南中的程式碼能提供穩固基礎。如果你只是需要資料,Thunderbit 會是更快的捷徑。不管哪種方式,你都不必再卡在只抓到 16 個 pin、對著空白螢幕發呆了。
想了解更多關於爬蟲與資料擷取的內容,歡迎參考我們的指南:如何用 Python 做網頁爬蟲、最佳自動化網頁爬蟲工具、以及將網站資料抓取到 Excel。你也可以查看 Thunderbit 價格頁,或到 Thunderbit YouTube 頻道 看教學影片。
常見問題
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 最好的免程式替代方案是什麼?
Thunderbit 的 AI Web Scraper 可以在 2 次點擊內擷取 Pinterest pin 資料——包含標題、圖片、URL、描述——並內建匯出到 Google Sheets、Excel、Airtable 或 Notion。它會自動處理 JavaScript 渲染、無限捲動與反機器人挑戰,所以你完全不需要寫或維護任何程式。
了解更多


