Lemon8 Media Scraper: Images, Videos & Downloads
Pricing
from $1.00 / 1,000 results
Lemon8 Media Scraper: Images, Videos & Downloads
Lightweight Lemon8 scraper for extracting image and video URLs from posts, with optional media downloads. Built for fast, clean media collection without comments, captions, or other post details.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
9
Total users
2
Monthly active users
8 days ago
Last modified
Categories
Features
Share
Lemon8 Media Scraper: Image and Video URLs from Any Post
Lemon8 Media Scraper turns any Lemon8 post, or a batch of posts found by keyword, into a clean feed of image and video URLs. Paste post links or set a search term and region, and get every media URL a post carries, already upgraded to its higher-quality variant, with an option to download the actual files into the run's storage. Schedule it and turn on incremental mode to get only new and changed posts on every run, then export the results as JSON, CSV or Excel, or read them through the API.
Why This Scraper?
- Two ways to find posts. Paste exact Lemon8 post links, or search by keyword and region through Lemon8's discovery page.
- Clean media, nothing else. Every image and video URL from a post, with thumbnails converted to their higher-quality variant by default.
- Optional file download. Pull the actual image and video files into the run's storage, not just links, when you need copies rather than references.
- Any Lemon8 region. Point it at the region code for the market you care about, the same way the Lemon8 app itself is localized.
- Built for schedules. Turn on incremental mode and recurring runs return only new and changed posts, not the same posts every time.
- Resume without re-paying. Continue an interrupted pull by pasting its run or dataset id, and posts already collected there are skipped.
- Pipe results into your apps. Send a summary of every record to Notion, Linear or Airtable through Apify's connectors, no extra script needed.
Use Cases
- Content archiving: save images and videos from posts before they are edited or taken down.
- Dataset building: collect batches of images and videos for a training or research dataset.
- Visual trend research: track the styles, colors and formats trending in a niche or region.
- Competitor and creator monitoring: watch an account's or a keyword's posts on a schedule and catch new content as soon as it is up.
- Personal backup: pull your own account's post media out of Lemon8 into your own storage.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
postId, groupId | "7543408422994264589" |
postUrl, url | "https://www.lemon8-app.com/@username/7543408422994264589?region=us" |
title, content | post title and text without HTML |
articleClass | post type, for example Gallery or Video |
likes, saves, commentCount | engagement counts |
authorUserId, authorUsername, authorNickname | the author |
authorAvatar, authorFollowers | author avatar and follower count |
hashtags | hashtags on the post |
topComments | up to 5 comments from the post page (text, likes, replies, author, time) |
imageCount, videoCount | 2, 0 |
images | array of image objects, one per extracted image |
images[].url | "https://example-cdn.lemon8-app.com/sample-image-1.webp" |
images[].alt, images[].type | "", "image" |
images[].keystoreKey | "7543408422994264589_img_0.webp" (only when downloadMedia is on) |
videos | array of video objects, one per extracted video |
videos[].url, videos[].poster | video file and its poster image |
videos[].keystoreKey | "7543408422994264589_vid_0.mp4" (only when downloadMedia is on) |
videoUrl, thumbnailUrl | video file (video posts only) and cover image |
keyword, category, region | how the post was reached |
sourceMode, scrapedAt | mode used and scrape time |
changeType | "NEW" (incremental mode only) |
changedFields | ["videos"] (incremental mode only) |
firstSeenAt, lastSeenAt | "2026-07-31T03:00:00Z" (incremental mode only) |
The post detail fields come from the same post page as the media, so they add no extra requests. In incremental mode the counts, comments, follower count, scrapedAt and the source fields are returned but never make a post UPDATED.
The last four fields (changeType, changedFields, firstSeenAt, lastSeenAt) are added only when incrementalMode is on. A normal run's rows carry the media fields and the post detail fields above, nothing more.
Output views
The dataset has these views in the Console: Media Overview (title, author, engagement and counts), Images, Videos, Post Details (text, hashtags, comments, source fields) and Changes (incremental fields). Every field is declared in the dataset schema, so exports have stable columns.
How to Use
- Choose your input: paste specific post URLs, or set a search term and region to find posts by keyword.
- Pick which media to keep (images, videos, or both), and whether to only collect links or also download the files.
- Set Limit to control how many posts are processed and how much the run costs, then click Start.
- Read the results from the dataset, or download them as JSON, CSV or Excel.
Search discovery in one region:
{"searchTerm": "skincare","region": "us","limit": 20,"saveImages": true,"saveVideos": true}
Direct post URLs with file download:
{"postUrls": ["https://www.lemon8-app.com/@username/7543408422994264589","https://www.lemon8-app.com/@another/7550145067198005791"],"downloadMedia": true}
Recurring monitoring with incremental mode:
{"searchTerm": "streetwear","region": "sg","limit": 50,"incrementalMode": true,"stateKey": "streetwear-sg-watch"}
Resume an interrupted pull:
{"searchTerm": "travel","region": "au","limit": 100,"resumeFromRunId": "<previous run or dataset id>"}
Modes
| Mode | Input used | What you get |
|---|---|---|
auto (default) | postUrls, else searchTerm | Your own URLs if you set any. The example postUrls run only when you set none of the search or saved-task inputs listed under "Default changed" below; otherwise a keyword search. |
post | postUrls | The posts you list. |
discover | keywords, region | About 50 posts per keyword, in order, up to the cap. |
profile | profileUrls | Posts linked from each profile page or @username. |
feed | feedCategories | First page of each category feed, about 10 posts each. |
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/lemon8-media-scraper").call(run_input={"searchTerm": "fashion", "region": "us", "limit": 20})for post in client.dataset(run["defaultDatasetId"]).iterate_items():print(post["postId"], post["imageCount"], post["videoCount"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/lemon8-media-scraper').call({ searchTerm: 'fashion', region: 'us', limit: 20 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Resume and recurring updates
- Resume (
resumeFromRunId) points this run at a previous run or dataset id so the actor knows which posts it already saw there. - Incremental mode (
incrementalMode) is for scheduled runs over the same posts or search. Each row is classifiedNEW,UPDATED(withchangedFields), orUNCHANGED(suppressed and not billed unlessemitUnchangedis on).EXPIREDis never detected unlessemitExpiredis on, and even then only once a run has scanned every tracked post to its natural end; a capped run or a resumed run skips EXPIRED detection that time rather than risk a wrong result.REAPPEAREDshows up only when a post previously markedEXPIREDby such a run is found again on a later run, it does not appear on a first run or under normalNEW/UPDATEDconditions. Ignore fields when detecting changes (ignoreFieldsForChanges): list field names, or a dotted path such asimages.altfor a key inside every item of a list, that must not make a post UPDATED or appear inchangedFields. The fields stay in the output; changing the list never re-marks your saved baseline as updated. Rotating CDN signatures and hostnames in image and video links are already ignored automatically. stateKeynames or shares the stored state. Leaving it empty derives a key from the mode and its inputs (postUrls/searchTerm,keywords,profileUrlsorfeedCategories),regionand the media options, so two differently configured runs never mix state. Raisinglimitalone never starts a new baseline.- Cosmetic link changes (a different delivery host, or a refreshed access token on an otherwise identical image or video) are normalized before comparing posts, so a post whose media has not actually changed is never marked
UPDATEDjust because its link was reissued. - With incremental mode off, output is exactly as in a normal run.
URL Mode
postUrls accepts these URL shapes (tracking parameters such as utm_source are ignored):
| Shape | Example | Behaviour |
|---|---|---|
| Post detail | https://www.lemon8-app.com/@05luvlee/7535454724489986574?region=us | Scrapes that post. ?region= is optional. |
Discovery (/discover/<term>, older path) | https://www.lemon8-app.com/discover/fashion?region=us | Lists posts for that keyword, up to Limit. |
Discovery (/experience/<term>) | https://www.lemon8-app.com/experience/fashion?region=us | Same as above. |
| Discovery in another region | https://www.lemon8-app.com/discover/fashion?region=jp | The region is taken from the URL. |
Feed (/feed/<category>) | https://www.lemon8-app.com/feed/food | Scrapes the first page of that category feed (about 10 posts). |
| Profile page | https://www.lemon8-app.com/@05luvlee?region=us | Scrapes the posts linked from the profile page, up to Limit. |
Topic page (/topic/<id>) | https://www.lemon8-app.com/topic/6880245568946880518?region=us | Scrapes the posts linked from the topic page, up to Limit. sourceMode is topic. |
The postUrl field of a post URL you pass is returned exactly as you typed it (a relative path gets the site host added). If none of your URLs is supported, the run ends with the status message No supported Lemon8 URL in postUrls.
Anything else (/tag/, /hashtag/, /search?q=, a bare numeric id, or the v. and m. hosts) is skipped and logged as a warning that starts with WARNING: unsupported URL skipped.
Default changed: postUrls now ships with one example URL per shape above. In auto mode the examples run only when you leave the list untouched and set none of the following: a searchTerm other than "fashion", keywords, profileUrls, incrementalMode, stateKey, resumeFromRunId, or a region other than us. If you set any of those and leave the example list as is, the examples are dropped: keywords or a custom search term run a keyword search, profileUrls scrape those profiles, and the other settings run the keyword search for searchTerm in your region, so saved tasks and schedules that never sent postUrls keep their earlier behavior and their saved incremental state. To search by keyword with no other setting, clear the list. postUrls always runs when it holds your own URLs.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify > Settings > Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. If the picker is empty, you haven't authorized a connector yet.
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
postUrls | array | five example URLs (one per supported shape) | Lemon8 URLs to scrape, see URL Mode above. When this holds your own URLs, searchTerm is ignored; the example list is dropped in the cases listed under "Default changed". |
searchTerm | string | "fashion" | Search keyword used to find posts on Lemon8's discovery page. Used when postUrls is empty, when the example postUrls are dropped (see "Default changed"), and in discover mode when Keywords is empty. |
mode | string | "auto" | auto (your own postUrls if set, else searchTerm; see "Default changed"), post, discover (keywords), profile (profile URLs) or feed (category feeds). A chosen mode uses only its own input. |
keywords | array | none | Keywords for discover mode, about 50 posts each, taken in order up to the cap. Also used in auto mode once postUrls is cleared. |
profileUrls | array | none | Profile pages or @usernames for profile mode. |
feedCategories | array | ["foryou"] | Feed mode: foryou, food, beauty, fashion, home, fitness, health, relationship, travel, photography, pet, reading, cars, outdoors (first page of each, about 10 posts). A /feed/<category> URL in postUrls works too. |
region | string | "us" | Region code passed to Lemon8 (for example us, au, nz, jp, th, id, vn, my, sg, ca). This is a free-text field, not a fixed list. |
limit | integer | 2 | Maximum number of posts to return, from 1 to 1000. |
saveImages | boolean | true | Extract image URLs from each post. |
saveVideos | boolean | true | Extract video URLs from each post. |
downloadMedia | boolean | false | Also download each image and video file into the run's key-value store, increasing run time and storage. |
highQuality | boolean | true | Convert thumbnail image URLs to their higher-quality variant. |
proxy | object | none (prefill shown in the console: a managed connection for country US) | Connection settings for requests. When the managed connection is turned on, the actor also keeps an alternate connection in reserve and switches to it automatically if a request is refused twice in a row. Leaving it off sends requests directly, with no automatic switch. |
resumeFromRunId | string | none | Paste a previous run or dataset id to seed this run with the posts it already found there. |
incrementalMode | boolean | false | Turn on for daily or recurring monitoring, so a run returns only new and changed posts against the previous run. |
stateKey | string | none | Name a monitoring campaign explicitly, or leave empty to derive one automatically from the mode and its inputs (postUrls/searchTerm, keywords, profileUrls or feedCategories), region and the media options. |
emitUnchanged | boolean | false | Also return (and bill) posts that have not changed since the last run, marked UNCHANGED. |
emitExpired | boolean | false | Also return (and bill) posts that were present before but are no longer found, marked EXPIRED, once a run fully scans every tracked post. |
ignoreFieldsForChanges | array | none | Incremental mode: field names or dotted paths (for example images.alt) that never make a post UPDATED. The fields stay in the output. |
mcpConnectors | array | none | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | none | Notion connector only: page under which item pages are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run, from 1 to 1000. Does not affect the dataset. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"postId": "7543408422994264589","postUrl": "https://www.lemon8-app.com/@username/7543408422994264589?region=us","images": [{"url": "https://example-cdn.lemon8-app.com/sample-image-1.webp","alt": "","type": "image"}],"videos": [{"url": "https://example-cdn.lemon8-app.com/sample-video-1.mp4","poster": "https://example-cdn.lemon8-app.com/sample-poster-1.webp","type": "video"}],"imageCount": 1,"videoCount": 1}
Plan Requirement
On paid Apify plans the default datacenter connection works and no residential proxy plan is needed: Lemon8 pages loaded in testing through Apify datacenter proxies on a paid account. The only block seen was a rare one-off HTTP 429 on a post link carrying extra tracking parameters, which the actor retries on the same connection. Apify free plans do not include Apify proxy access at all, so on a free plan the actor logs a notice and continues on a backup connection, and fails with a clear message if no page can be loaded.
The default proxy input uses the managed connection for the selected region. If a request is refused twice in a row, the actor switches to an alternate connection and logs: "Served over the backup connection (the default connection was unavailable)." If the connection is refused for the account, the run logs a notice that Apify free plans do not include residential proxies and continues on the backup connection. If no page can be read at all, the run fails with a clear message (for example "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search.") instead of returning an empty success. Leaving the proxy input off sends requests directly.
FAQ
How much does it cost?
Pricing is pay per event: one actor start event per run (apify-actor-start) and one dataset item event per row pushed to the dataset (apify-default-dataset-item). The Pricing tab on the actor page shows the current rates for your plan. Nothing else is charged: no extra fee for comments, downloads or modes, and suppressed UNCHANGED rows in incremental mode are not billed. Use Limit (hard cap 1000 per run) to cap the size, and therefore the cost, of any run.
Is it legal to scrape Lemon8?
This actor collects only media URLs from publicly viewable Lemon8 posts. You are responsible for how you use the results: follow Lemon8's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. The images and videos themselves may carry their own copyright or other rights held by the original poster.
Can I get only new or changed posts on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and changed posts, and unchanged ones are not billed unless you turn that on too.
Why did a run return no items instead of some media?
If the given post URLs could not be read (deleted, private, or an unrecognized page), or a search and region combination matched nothing, the run stops with a clear status message and returns nothing rather than a placeholder row. This is a normal, successful outcome, not a failure.
Why might a run fail instead of returning an empty result?
A run fails outright only when resumeFromRunId points to a run or dataset that cannot be read (a bad or inaccessible id), or when incrementalMode is combined with resumeFromRunId while saved incremental state already exists for that state key (remove one or set a different stateKey). Individual posts that fail to load are skipped and logged, they don't fail the whole run.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
π Want more Lemon8 data?
Pair this actor with these related scrapers from the same team:
| π± Lemon8 Feed Scraper Scrape Lemon8 feeds across 22 categories and 10+ regions. Extract posts, images, videos... | π± Lemon8 Profile Scraper Scrape Lemon8 user profiles with automated multi-profile discovery. Extract profile data... |
| π± Lemon8 Search Scraper Scrape Lemon8 posts by keyword across multiple regions. Extract posts, images, videos... | π± Universal Media Extractor Extract videos, audio, and metadata from 1000+ websites including YouTube, TikTok... |
| π± Redditβ‘ Lightning Scrape Reddit posts, comments, and media from any subreddit or user profile - no login or... | π± Truth Social Scraper Scrape public Truth Social profiles, posts, media, metrics, author data, and complete... |
π Browse all abotapi scrapers
π¬ Support
- π Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- π οΈ Need another site, extra fields or a private build? Email contact@abotapi.com.
- β Enjoying it? A quick review on the actor page helps other users find it.