Facebook Profile Posts Scraper
Under maintenancePricing
from $20.00 / 1,000 results
Facebook Profile Posts Scraper
Under maintenancePaste 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
Maintained by CommunityActor stats
0
Bookmarked
25
Total users
14
Monthly active users
4 days ago
Last modified
Categories
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
| Field | Description |
|---|---|
profileUrl | One 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. |
profileUrls | Several profiles as an array. numberOfPosts applies per profile. |
numberOfPosts | Maximum 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. |
scrapeAll | Keep scrolling until the target count, the date boundary, or the end of the feed (default on). |
timeSince / timeUntil | Inclusive date range (yyyy-mm-dd, UTC). Posts carry real timestamps; the actor stops scrolling once the feed passes below timeSince. |
cookies / fbEmail + fbPassword | Session — see Authentication. |
proxySessionId | Stable Apify proxy session id pinning ONE exit IP across runs (or the FB_PROXY_SESSION env var). |
useBrowser | Force 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_PASSWORDsecret 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
cookiesinput or theFB_COOKIESsecret env var (a Cookie-Editor JSON export, or aname=value; name2=value2string). These are only a seed — once adopted, the self-refreshing stored session takes priority. - Always set
FB_PROXY_SESSION(orproxySessionId). 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_HTMLin 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.
