Back to all nuggets
Python
python
Published on July 15, 2026
Code Snippet
import requests
import time
from collections import Counter
BASE = "https://graph.facebook.com/v20.0"
# ── helpers ──────────────────────────────────────────────────────────────
def g(url: str, token: str, params: dict = None) -> dict:
"""GET a Graph API endpoint, automatically injecting the access token."""
p = params or {}
p["access_token"] = token
resp = requests.get(url, params=p, timeout=30)
resp.raise_for_status()
return resp.json()
def get_all(url: str, token: str, params: dict = None, max_pages: int = 50) -> list:
"""
Follow paging.next until exhausted, returning all items as a flat list.
Sleeps 0.3 s between pages to stay inside rate limits.
"""
results = []
page = 1
while url and page <= max_pages:
data = g(url, token, params or {})
if "error" in data:
print(f" API error on page {page}: {data['error'].get('message','')[:80]}")
break
results.extend(data.get("data", []))
# The next cursor is a full URL — clear params so they are not doubled
url = data.get("paging", {}).get("next")
params = {}
page += 1
time.sleep(0.3)
return results
# ── example: fetch posts and score engagement ────────────────────────────
def analyse_page(page_id: str, token: str) -> dict:
posts = get_all(
f"{BASE}/{page_id}/posts",
token,
params={"fields": "id,message,created_time,likes.summary(true),comments.summary(true)"},
)
engagement = []
all_tags: list[str] = []
for post in posts:
likes = post.get("likes", {}).get("summary", {}).get("total_count", 0)
comments = post.get("comments", {}).get("summary", {}).get("total_count", 0)
text = post.get("message", "") or ""
tags = [w[1:].lower() for w in text.split() if w.startswith("#")]
all_tags.extend(tags)
engagement.append({
"id": post["id"],
"date": post["created_time"][:10],
"likes": likes,
"comments": comments,
"engagement": likes + comments,
"preview": text[:80],
})
engagement.sort(key=lambda x: x["engagement"], reverse=True)
return {
"total_posts": len(posts),
"top_posts": engagement[:5],
"top_hashtags": Counter(all_tags).most_common(10),
}
# ── usage ────────────────────────────────────────────────────────────────
# token = "YOUR_LONG_LIVED_PAGE_TOKEN"
# page_id = "YOUR_PAGE_ID"
# report = analyse_page(page_id, token)
# print(f"Total posts: {report['total_posts']}")
# for p in report["top_posts"]:
# print(f" {p['date']} ❤ {p['likes']} 💬 {p['comments']} {p['preview']}")
The Meta Graph API returns results one page at a time. Every response
that has more data includes a paging.next cursor URL.
The pattern below wraps that into a single reusable get_all()
helper so you never have to think about pagination again.
Key ideas:
- A thin
g()wrapper attaches the access token to every request. get_all()followspaging.nextuntil it disappears or a page limit is hit.- A small
time.sleep()between pages keeps you well under the API rate limit. - Errors inside the JSON body are caught early so a single failed page does not crash the whole run.
Once you have the raw list of posts you can layer on engagement scoring, hashtag frequency counts, or keyword-based sentiment — all shown in the code below.
Love this nugget?
Support our work to get exclusive premium nuggets and early access via a personal activation link.
Support Now & Unlock Exclusive Content