Facebook Profile Posts Scraper avatar

Facebook Profile Posts Scraper

Under maintenance

Pricing

from $20.00 / 1,000 results

Go to Apify Store
Facebook Profile Posts Scraper

Facebook Profile Posts Scraper

Under maintenance

Paste a Facebook page or profile URL and get that account's posts for any period. Date filtering, multi-profile input, auto-pagination, self-renewing login session. Returns text, author, timestamp, reactions, comments, shares and media.

Pricing

from $20.00 / 1,000 results

Rating

0.0

(0)

Developer

code craker

code craker

Maintained by Community

Actor stats

0

Bookmarked

25

Total users

14

Monthly active users

4 days ago

Last modified

Share

Paste a Facebook page or profile URL and get that account's posts as structured data — text, author, publish time, reaction breakdown, comment and share counts, photos and videos. Supports several profiles per run, a date range with early-stop scrolling, and a self-renewing login session.

Input

FieldDescription
profileUrlOne page/profile: https://www.facebook.com/nasa, a profile.php?id=... URL, a /people/ URL, a bare vanity name or numeric id. Any post URL on the page resolves to its owner. Several profiles can be pasted one per line.
profileUrlsSeveral profiles as an array. numberOfPosts applies per profile.
numberOfPostsMaximum posts to return per profile (default 25). Results are written to the dataset every 50 posts while paginating, so a timeout or abort keeps what was collected.
scrapeAllKeep scrolling until the target count, the date boundary, or the end of the feed (default on).
timeSince / timeUntilInclusive date range (yyyy-mm-dd, UTC). Posts carry real timestamps; the actor stops scrolling once the feed passes below timeSince.
cookies / fbEmail + fbPasswordSession — see Authentication.
proxySessionIdStable Apify proxy session id pinning ONE exit IP across runs (or the FB_PROXY_SESSION env var).
useBrowserForce the rendered-browser feed instead of the direct HTTP timeline (see How it paginates). Off by default.

How it paginates (and why it is cheap)

The actor does not scroll a rendered page. It fetches the profile HTML once over plain HTTP (the first posts, the session tokens, the profile id and the first cursor are all in it) and then replays Facebook's own timeline pagination query (ProfileCometTimelineFeedRefetchQuery) directly, ten posts per call. No Chromium, none of Facebook's ~5 MB of JavaScript per run, no render waits and no memory growth — a run needs about 1 GB and pays only for the post data itself.

The query's doc_id and variables are not in the HTML, so they come from a request template: the first run for an account (or the first after Facebook changes the query) loads the feed in the browser, captures the pagination request, saves it to the session store and continues by replaying it. Every later run skips the browser. The browser also remains the fallback whenever the direct path cannot proceed (a login is needed, the template is rejected, the page shape changed).

Authentication

Facebook login-walls most timelines for anonymous visitors, so the actor needs a session from a throwaway account (never a personal one):

  • Recommended: set the FB_EMAIL + FB_PASSWORD secret environment variables (2FA disabled) — the actor logs in once, then keeps the session alive by itself: the refreshed cookies are written back to a persistent store after every run and the pinned proxy session (FB_PROXY_SESSION) keeps the account on one exit IP, which is what stops Facebook invalidating it.
  • Or provide cookies directly: the cookies input or the FB_COOKIES secret env var (a Cookie-Editor JSON export, or a name=value; name2=value2 string). These are only a seed — once adopted, the self-refreshing stored session takes priority.
  • Always set FB_PROXY_SESSION (or proxySessionId). Without it every run uses a fresh residential exit IP, and Facebook invalidates a session it sees hopping between IPs within hours — a dead session is the most common cause of failed or empty runs.

The session is verified with one small HTTP request before anything else happens. If Facebook rejects it, the actor tries the other copies it knows (the shared facebook-session store, FB_COOKIES) and, when none works and no login credentials are set, fails immediately with a clear message — a dead session costs a fraction of a cent instead of a browser run.

Output

One dataset item per post:

{
"post_id": "1234567890123456",
"url": "https://www.facebook.com/NASA/posts/...",
"message": "Full post text...",
"text": "Full post text...",
"timestamp": 1787568447,
"createdTime": "2026-08-21T19:05:34.000Z",
"reactions_count": 1809,
"comments_count": 147,
"reshare_count": 300,
"reactions": { "like": 1500, "love": 200, "care": 30, "haha": 20, "wow": 40, "sad": 10, "angry": 9 },
"author": { "id": "...", "name": "NASA", "url": "https://www.facebook.com/NASA", "username": "NASA" },
"image": { "uri": "https://...", "width": 720, "height": 480 },
"video": null,
"attached_post": null,
"profileHandle": "nasa",
"profileUrl": "https://www.facebook.com/nasa"
}

Tips

  • An unavailable page (deleted, restricted, renamed) is skipped with a warning instead of failing the run.
  • Public pages often serve their first posts even without a session, so a cookie-less run may still return the newest few posts — but a session is required for reliable, deep scraping.
  • Check DEBUG_SCREENSHOT / DEBUG_HTML in the run's key-value store when a run returns nothing.
  • Memory: 1 GB is enough for the direct HTTP path at any depth. Give the run 2–4 GB only if it has to fall back to the browser (the log says so), where Facebook's rendered feed keeps every scrolled post in memory.