לפני כמה חודשים אחד המהנדסים שלנו הראה לי סקריפט Python שכתב בסוף השבוע. המטרה שלו הייתה לשלוף תמונות השראה למוצרים מ-Pinterest עבור פרויקט מחקר שוק. הוא הריץ את הסקריפט, והתוצאה הייתה… 16 Pins. מתוך Board של יותר מ-2,000. הוא בהה במסך, אחר כך בי, ואמר: "אני חושב ש-Pinterest עושה ממני צחוק."
הוא ממש לא היחיד. זו בלי ספק התסכול הכי נפוץ שאני רואה אצל מפתחים שמנסים לגרד נתונים מ-Pinterest עם Python. מפעילים requests ו-BeautifulSoup, נכנסים לכתובת של Pinterest, ומקבלים או קומץ פריטים או מעטפת HTML ריקה. למה זה קורה? כי Pinterest היא אפליקציית SPA שמרונדרת כולה ב-JavaScript — בקשת HTTP סטטית פשוט לא רואה את התוכן האמיתי. במדריך הזה אסביר למה זה קורה, אילו שיטות באמת עובדות (Playwright, יירוט API פנימי, וגם כלים ללא קוד כמו Thunderbit), ואביא דוגמאות קוד שלב-אחר-שלב לגרידה של Pins, Boards, פרופילי משתמשים, Infinite Scroll ותמונות ברזולוציה מלאה. אם אתם רוצים לבנות סקרייפר ברמת production או פשוט למשוך נתונים במהירות — המאמר הזה בשבילכם.
מהי גרידת Pinterest?
גרידת Pinterest היא תהליך של חילוץ נתונים מפלטפורמת Pinterest בצורה אוטומטית — למשל תמונות של Pins, כותרות, תיאורים, שמות Boards, מספרי עוקבים וכתובות URL. במקום לגלוש ידנית ולשמור Pins אחד-אחד, משתמשים בקוד (או בכלי) כדי לאסוף נתונים מובנים מתוצאות חיפוש, Boards או פרופילים בקנה מידה גדול.
עם מעל 240 מיליארד Pins בפלטפורמה ו-619 מיליון משתמשים פעילים חודשית נכון לסוף 2025, Pinterest היא אחד ממקורות הנתונים הוויזואליים העשירים ביותר ברשת. עבור עסקים, זה זהב — בין אם אתם עוקבים אחרי טרנדים במוצרים, בודקים תוכן של מתחרים או בונים רשימות לפנייה למשפיענים.
למה לגרד Pinterest עם Python?
Pinterest כבר מזמן לא רק לוח השראה למתכנני חתונות. זהו כלי רציני ל-Business Intelligence — 85% ממשתמשי Pinterest השבועיים רכשו משהו בעקבות Pin של מותג, ו-96–97% מהחיפושים המובילים הם ללא מותג, כלומר המשתמשים מגיעים עם כוונה, אבל בלי נאמנות למותג מסוים. זו הזדמנות עצומה לגילוי — והיא מסבירה למה כל כך הרבה צוותים רוצים נתוני Pinterest מסודרים.
כך זה נראה לפי צוותים:
| צוות | נתונים נדרשים | ערך עסקי |
|---|---|---|
| תפעול Ecommerce | תמונות מוצרים, מחירים, אסתטיקה טרנדית | תמחור תחרותי, מלאי שמבוסס על טרנדים |
| שיווק | ביצועי Boards, מעורבות ב-Pins, תוכן של מתחרים | אסטרטגיית תוכן, השוואת קמפיינים |
| מכירות / יצירת לידים | פרופילים של יוצרים, מספרי עוקבים, פרטי קשר | פנייה למשפיענים, מיקוד בשיתופי פעולה |
| נדל"ן | Pins של עיצוב בית, טרנדים בעיצוב, פריסות חדרים | צילום נכסים, הנחיות לסטייג'ינג |
| יוצרי תוכן | נושאים חמים, פורמטים פופולריים, נושאים עונתיים | לוח תוכן, מחקר על סגנון ויזואלי |
והנה הקאץ': ה-API הרשמי של Pinterest מוגבל. הוא דורש חשבון עסקי, אישור (כולל הדגמת וידאו של האפליקציה), ומספק גישה רק לנתונים של החשבון שלכם. אם רוצים לעיין ב-Boards ציבוריים, בתוצאות חיפוש או בפרופילים של מתחרים — גרידה היא האלטרנטיבה הפרקטית. לכן הרבה צוותים פונים ל-Python — או לכלים ללא קוד כמו Thunderbit כשצריך תוצאות בלי כל הסיבוך.
למה BeautifulSoup לבד נכשל ב-Pinterest ומה כן עובד באמת
אם ניסיתם לגרד את Pinterest עם requests + BeautifulSoup וקיבלתם 16 פריטים או דף ריק, אתם לא מדמיינים. Pinterest בנויה עם React וכל התוכן שלה מרונדר ב-100% באמצעות JavaScript. כשמבקשים URL של Pinterest עם בקשת HTTP רגילה, השרת מחזיר שלד HTML מינימלי — כמה תגיות <link> ו-<script>, ו-<div> ריק שבו React “מעלה” את האפליקציה. כל כרטיסי ה-Pin, התמונות, הכותרות והגריד מוזרקים רק אחרי ש-JavaScript רץ בדפדפן.
אין הרצת JavaScript = אין Pins.
אז מה כן עובד? הנה השוואה בין השיטות העיקריות:
| גישה | תומכת ב-JS? | משיגה את כל הנתונים? | מורכבות | מתאימה במיוחד ל... |
|---|---|---|---|---|
requests + BeautifulSoup | לא | ~0–16 פריטים | נמוכה | לא מתאימה ל-Pinterest |
| Selenium / Playwright | כן | כן, עם לוגיקת גלילה | בינונית | שליטה מלאה, תהליכי Python |
| יירוט API פנימי של Pinterest | כן | כן, JSON מחולק לעמודים | גבוהה | מקסימום נתונים, בלי דפדפן |
| Scraper API של צד שלישי | כן | משתנה | נמוכה | סקייל בלי תשתית |
| כלי ללא קוד (Thunderbit) | כן | מובנה באמצעות AI | נמוכה מאוד | משתמשים לא טכניים, תוצאות מהירות |
למדריך הזה אני ממליץ על Playwright כפתרון Python. הוא מרנדר JavaScript, תומך בסימולציית גלילה, מתוחזק היטב (78,600+ כוכבים ב-GitHub, עם צמיחה של 180% משנה לשנה במודעות דרושים), והוא מהיר ב-35–45% מ-Selenium במדדים שונים. אם אתם מעדיפים דרך ללא קוד — גם לזה נגיע.
ה-API הרשמי של Pinterest מול גרידה ב-Python מול No-Code: מה עדיף?
לפני שמתחילים לכתוב קוד, כדאי לשאול: בכלל צריך? הנה מסגרת החלטה:
| קריטריון | Pinterest API | גרידה ב-Python | Thunderbit (ללא קוד) |
|---|---|---|---|
| נדרש אישור | חשבון עסקי + הדגמת וידאו | לא | לא |
| גישה ל-Pins/Boards ציבוריים | מוגבלת (רק נתוני החשבון) | מלאה | מלאה |
| הורדת תמונות ברזולוציה מלאה | משתנה | כן, באמצעות ניתוח URL | כן, באמצעות חילוץ תמונות |
| טיפול ב-Infinite Scroll | לא רלוונטי | כן, עם קוד | אוטומטי |
| תחזוקה נדרשת | נמוכה | גבוהה (סלקטורים נשברים) | אין (AI מסתגל) |
| ייצוא ל-Sheets/Airtable | ידני | קוד מותאם אישית | מובנה |
| זמן הקמה | שעות–ימים | 30–60 דק׳ | 2 דקות |
אם אתם משווקים, אנשי תפעול ב-ecommerce, או פשוט רוצים נתוני Pinterest בגיליון בלי לכתוב או לתחזק סקריפטי Python, Thunderbit AI Web Scraper הוא המסלול המהיר. פותחים כל דף Pinterest, לוחצים "AI Suggest Fields", אחר כך "Scrape", ומייצאים ישר ל-Google Sheets, Excel, Airtable או Notion. תכונת הגרידה של תתי-עמודים יכולה אפילו לעקוב אחרי קישורי Pin בודדים ולהעשיר את הנתונים אוטומטית. ראיתי חברי צוות שמעולם לא כתבו שורת קוד אחת מושכים יותר מ-500 Pins ל-Google Sheet בפחות משלוש דקות.
אם אתם רוצים שליטה מלאה, רוצים לשלב את הגרידה בתוך pipeline ב-Python, או פשוט נהנים מהיצירה — המשיכו לקרוא.
הכנת סביבת Python לגרידת Pinterest
- רמת קושי: בינונית
- זמן נדרש: כ-30–60 דקות (כולל כתיבה ובדיקות)
- מה צריך: Python 3.9+, דפדפן Chrome (לבדיקות), גישה לטרמינל/שורת פקודה
התקנת Playwright והתלויות
קודם ניצור תיקיית פרויקט ונגדיר סביבה וירטואלית:
mkdir pinterest-scraper
cd pinterest-scraper
python -m venv venv
source venv/bin/activate # ב-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 חוסמת חתימות ברירת מחדל של דפדפנים headless, לכן כדאי להשתמש במחרוזת מציאותית:
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: הפעלת דפדפן headless וטעינת הדף
זהו הסט־אפ המרכזי של 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) # מחכים לטעינת ה-JS וה-Pins הראשונים
אחרי שהקוד רץ, אמורים להיטען ה-Pins הראשונים — בדרך כלל 25–50.
שלב 3: חילוץ נתוני Pin מהדף
Pinterest עוטפת כל Pin בתוך div עם data-test-id='pinWrapper'. בפנים תמצאו קישור (<a>) עם כתובת ה-Pin והכותרת (דרך aria-label), ו-<img> עם כתובת התמונה הממוזערת.
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)
כדאי להשתמש ב-utf-8-sig אם אתם פותחים את קובץ ה-CSV ב-Excel — זה מונע תווים משובשים.
גרידת Boards שלמים ופרופילי משתמשים ב-Pinterest
זו חסרה גדולה במדריכים הקיימים. לא מצאתי מדריך מתחרה אחד שמכסה לעומק גרידת Boards או פרופילים — למרות שזו אחת הדרישות הכי נפוצות בפורומים. משתמשים רוצים להוריד את כל ה-Pins מ-Board מסוים, לארגן תמונות לתיקיות לפי Board, ולשלוף נתוני פרופיל כמו מספר עוקבים ורשימת Boards.
גרידת כל ה-Pins מכתובת של Board
כתובות Board נראות כך: 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
כתובות פרופיל נראות כך: https://www.pinterest.com/{username}/. מדף פרופיל אפשר לשלוף:
- מספר עוקבים/נעקבים: חפשו
div[data-test-id='follower-count'] - רשימת Boards: כל Board הוא כרטיס עם קישור ל-
/{username}/{board-name}/ - ספירת Pins כוללת: לפעמים מופיעה בכותרת הפרופיל
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"
# חילוץ קישורים ל-Boards
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}
כדי לגרד את כל ה-Pins בכל ה-Boards של פרופיל, עוברים על רשימת ה-Boards ומפעילים scrape_board() עבור כל אחד. אפשר גם לארגן את התמונות שהורדו אוטומטית לתיקיות נפרדות לפי Board.
בניית handler מקצועי ל-Infinite Scroll
זה החלק שמבדיל בין סקרייפר צעצוע לסקרייפר אמיתי. נקודת הכאב מספר 1 — וראיתי אותה בלפחות תריסר שרשורי פורום — היא שסקרייפרים מחזירים רק 16–25 פריטים כי הם לא גוללים מספיק, או שהם משתמשים במספר גלילות קבוע כמו for i in range(5): scroll() ומקווים לטוב.
זה לא אמין. Pinterest טוענת תוכן חדש במנות של כ-25 Pins, שמופעלות על-ידי אירועי גלילה. אם תגללו חמש פעמים, אולי תקבלו 125 Pins — או 75 אם הרשת איטית, או 150 אם המנות קטנות. צריך דפוס חכם יותר.
דפוס גלול-עד-שאין-תוכן-חדש
הנה פונקציית גלילה יציבה שעוקבת אחרי מזהים ייחודיים של Pins, משתמשת ב-timeout שניתן להגדיר, כוללת לוגיקת retry ומדפיסה התקדמות:
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" Scroll {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(" לא נמצאו Pins חדשים ב-3 גלילות רצופות. כנראה סוף התוכן.")
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
למה זה עובד טוב:
- Deduplication לפי href: לכל Pin יש URL ייחודי, ולכן משתמשים בו כמזהה. זה מונע ספירה כפולה כשה-DOM נבנה מחדש בזמן הגלילה.
- כלל שלוש הפעמים: אם שלוש גלילות רצופות לא מחזירות שום Pin חדש, עוצרים. זה מטפל במצב שבו הדף עדיין נטען אבל אין עוד תוכן.
- ג׳יטר אקראי בהשהיה: הוספת 0.5–1.5 שניות אקראיות בין גלילות גורמת לפעולה להיראות אנושית יותר ומפחיתה את הסיכוי להפעיל מנגנוני anti-bot.
- מגבלת max_scrolls: מונעת לולאות אינסופיות אם משהו משתבש.
טיפול במקרי קצה
- שבירת "More Ideas": בדפי Board, Pinterest לפעמים מוסיפה מקטע "More Ideas". אם אתם רוצים רק את ה-Pins המקוריים של ה-Board, אפשר לזהות את האלמנט הזה ולעצור בגלילה כשהוא מופיע.
- Rate limiting בסשנים ארוכים: אם אתם גוללים ב-Board עם אלפי Pins, Pinterest עלולה להתחיל להגביל תגובות. אם אתם רואים גלילות שמייצרות אפס Pins חדשים מדי פעם (אבל לא שלוש ברצף), הגדילו את ההשהיה ל-5 שניות ומעלה.
קבלת תמונות Pinterest ברזולוציה מלאה (לא thumbnails)
זה משגע אנשים. מגרדים הרבה Pins, מורידים את התמונות, והן כולן thumbnails זעירים של 236 פיקסלים. משתמשים בפורומים מתארים את זה כ"איכות זבל, כמו גודל קטן מדי". הפתרון הוא להבין את מבנה כתובות התמונות של Pinterest.
מבנה נתיב ה-URL של תמונות Pinterest
כל תמונות Pinterest מוגשות מ-https://i.pinimg.com/{size}/{hash}.jpg. החלק {size} קובע את הרזולוציה:
| נתיב גודל | ממדים | שימוש |
|---|---|---|
/236x/ | רוחב 236px | תצוגת גריד ברירת מחדל (מה שמקבלים בדרך כלל) |
/474x/ | רוחב 474px | רזולוציה בינונית |
/736x/ | רוחב 736px | תצוגת Pin מורחבת |
/originals/ | מידות ההעלאה המקוריות | רזולוציה מלאה |
פונקציית עזר: שדרוג כל URL של תמונת Pinterest לרזולוציה מלאה
הנה פונקציה שמשכתבת כל URL של תמונת Pinterest לאיכות הגבוהה ביותר הזמינה, עם לוגיקת fallback:
import requests as req
def upgrade_image_url(url, preferred_size="originals"):
"""משכתבת URL של תמונת Pinterest לרזולוציה הגבוהה ביותר."""
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))
כדאי להוסיף השהיית rate limiting בין הורדות. אני משתמש ב-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 ומוסיף מורכבות אמיתית ל-pipeline.
או — ואני קצת משוחד כאן, אבל זו באמת הדרך המהירה ביותר — אפשר להשתמש ב-Thunderbit כדי לגרד את Pinterest ולייצא לכל היעדים האלה בלחיצה אחת. בלי API keys, בלי service accounts, בלי קוד נוסף. הרחבת Chrome של Thunderbit מטפלת בייצוא באופן מובנה.
טיפים להימנע מחסימה בזמן גרידת Pinterest
מערכת האנטי-בוט של Pinterest מקבלת ציון קושי עקיפה 6/10 לפי ScrapeOps — לא טריוויאלית, אבל גם לא היעד הקשה ביותר. היא משתמשת בטביעת אצבע של הדפדפן, ניתוח התנהגות והגבלת קצב לפי IP. הנה מה שעובד:
- סיבוב User-Agents: השתמשו במאגר של מחרוזות Chrome אמיתיות ובחרו אחת אקראית לכל סשן.
- הוספת השהיות אקראיות: 2–5 שניות בין גלילות ובקשות, עם ג׳יטר. בלי פרוקסי, עדיף להגדיל ל-10–15 שניות.
- Viewport ריאלי: הגדירו
viewport={"width": 1920, "height": 1080}— לא מידות קטנות או חריגות. - פרוקסי לסקייל: אם אתם מגרדים אלפי Pins, סובבו residential proxies. בלי זה, צפויים חסימות IP אחרי כמה מאות בקשות.
- כבדו את
robots.txt: ה-robots.txtשל Pinterest חוסם רוב הסורקים האוטומטיים ויש בו כ-180 כללי disallow. קחו זאת בחשבון מבחינת תאימות. - הימנעו מגרידה בזמן התחברות: הישארו עם תוכן ציבורי בלבד, כשהחשבון לא מחובר. גרידה מאחורי התחברות מעלה גם סיכון משפטי וגם סיכון טכני.
Thunderbit מטפל אוטומטית באנטי-בוט ובאתגרי CAPTCHA דרך מנוע ה-AI שלו — עוד דבר אחד פחות לתחזק אם בוחרים במסלול ללא קוד.
שיקולים משפטיים ואתיים בגרידת Pinterest
אשמור את זה קצר כי זה לא מוקד המאמר, אבל זה חשוב.
תנאי השימוש של Pinterest (סעיף 2a) קובעים שאתם מסכימים לא "לגרד, לאסוף, לחפש, להעתיק או לגשת אחרת לנתונים או תוכן מ-Pinterest בדרכים לא מורשות, למשל באמצעות אמצעים אוטומטיים (ללא אישור מפורש מראש שלנו)." עם זאת, בתי משפט קבעו בדרך כלל שגרידת נתונים ציבוריים אינה מפרה את חוק Computer Fraud and Abuse Act — ראו hiQ נגד LinkedIn ו-Meta נגד Bright Data (ינואר 2024), שם קבע בית המשפט שגרידה של נתונים גלויים לציבור כאשר לא מחוברים לחשבון היא חוקית.
כמה כללי אצבע:
- גרדו רק תוכן ציבורי כאשר אינכם מחוברים לחשבון
- אל תשתמשו בנתונים שגרדתם לספאם או להתחזות למשתמשים
- כבדו זכויות יוצרים על תמונות — שלפו מטא-דאטה כשאפשר, והימנעו מהפצה מסחרית של תמונות מוגנות בלי אישור
- אם אתם מתכננים להשתמש בנתונים שגרדתם למטרה מסחרית, דברו עם עורך דין
למבט עמוק יותר על ההיבט המשפטי, ראו את המדריך שלנו על השלכות משפטיות של גרידת נתונים מהאינטרנט.
סיכום: מה למדתם ולאן ממשיכים מכאן
עכשיו אתם יודעים למה גרידה סטטית נכשלת ב-Pinterest (זו SPA מבוססת React — בלי JavaScript אין נתונים), איך להשתמש ב-Playwright כדי לגרד תוצאות חיפוש, Boards ופרופילי משתמשים, איך לבנות handler אמין ל-Infinite Scroll שלא נעצר אחרי 16 Pins, ואיך להגיע לתמונות ברזולוציה מלאה במקום thumbnails זעירים.
תקציר קצר של מה שחשוב:
requests+ BeautifulSoup לא יעבדו על Pinterest. אל תבזבזו על זה זמן.- Playwright הוא כלי Python הטוב ביותר למשימה — מהיר, נתמך היטב, ומרנדר JavaScript באופן טבעי.
- Infinite Scroll דורש לולאת גלילה מבוססת deduplication, לא מספר קבוע של גלילות.
- תמונות ברזולוציה מלאה דורשות שכתוב של נתיב ה-URL — עדיף
/736x/(כי/originals/מחזיר לעיתים קרובות 403). - גרידת Boards ופרופילים כמעט לא מקבלת מענה במדריכים קיימים, אבל היא פשוטה יחסית עם הסלקטורים הנכונים.
- למי שלא כותב קוד או לצוותים שרוצים מהירות, Thunderbit מאפשר לגרד Pinterest בשתי לחיצות ולייצא ל-Google Sheets, Excel, Airtable או Notion — בלי צורך ב-Python. אפשר לנסות בחינם דרך הרחבת Chrome.
אם אתם בונים pipeline ב-Python, הקוד במדריך הזה נותן בסיס חזק. אם אתם פשוט צריכים את הנתונים, Thunderbit הוא קיצור הדרך. בכל מקרה, כבר לא תישארו תקועים עם 16 Pins ומבט מבולבל.
לקריאה נוספת על גרידה וחילוץ נתונים, בדקו את המדריכים שלנו על איך לגרד נתונים מהאינטרנט עם Python, הכלים האוטומטיים הטובים ביותר לגרידת נתונים מהאינטרנט, ו-גרידת נתונים מאתר ל-Excel. אפשר גם לבדוק את תמחור Thunderbit או לצפות במדריכים ב-ערוץ YouTube של Thunderbit.
שאלות נפוצות
1. האם אפשר לגרד Pinterest עם BeautifulSoup?
לא בצורה יעילה לבדו. Pinterest מרנדרת את כל התוכן ב-JavaScript, לכן requests + BeautifulSoup רואה רק מעטפת HTML ריקה. צריך דפדפן headless כמו Playwright או Selenium כדי לרנדר את הדף קודם, או להשתמש בכלי ללא קוד כמו Thunderbit שמטפל ב-JS אוטומטית.
2. כמה Pins אפשר לגרד מ-Pinterest בסשן אחד?
זה תלוי בלוגיקת הגלילה ובהתמודדות עם אנטי-בוט. עם handler ל-Infinite Scroll ברמת production כמו במדריך הזה (deduplication, timeout, retry logic), אפשר לגרד באופן אמין מאות עד אלפי Pins לכל Board או שאילתת חיפוש. עבור Boards גדולים מאוד, צפו לכמה דקות של גלילה ואיסוף.
3. למה התמונות שגרדתי מ-Pinterest יוצאות קטנות?
ברירת המחדל של Pinterest היא thumbnails ב-/236x/ בתצוגת הגריד. כדי לקבל רזולוציה גבוהה יותר, משכתבים את נתיב התמונה ל-/736x/ או ל-/originals/. שימו לב ש-/originals/ מחזיר יותר ויותר שגיאות 403 נכון ל-2025, ולכן /736x/ הוא המקסימום האמין.
4. האם חוקי לגרד Pinterest?
גרידת נתונים ציבוריים מקובלת בדרך כלל לפי פסיקות עדכניות (למשל hiQ נגד LinkedIn, Meta נגד Bright Data), אבל תנאי השימוש של Pinterest אוסרים גישה אוטומטית לא מורשית. הישארו עם תוכן ציבורי, אל תשתמשו בנתונים לספאם, כבדו זכויות יוצרים, והתייעצו עם ייעוץ משפטי לשימוש מסחרי.
5. מה החלופה הטובה ביותר ללא קוד לגרידת Pinterest?
Thunderbit AI Web Scraper יכול לחלץ נתוני Pins מ-Pinterest — כותרות, תמונות, כתובות URL, תיאורים — בשתי לחיצות, עם ייצוא מובנה ל-Google Sheets, Excel, Airtable או Notion. הוא מטפל ברינדור JavaScript, ב-Infinite Scroll ובאתגרי אנטי-בוט אוטומטית, כך שלא צריך לכתוב או לתחזק קוד.
למידע נוסף


