Lemon8 Search Scraper - Posts, Comments & Media
Pricing
from $3.00 / 1,000 results
Lemon8 Search Scraper - Posts, Comments & Media
Scrape Lemon8 posts by keyword across multiple regions. Extract posts, images, videos, comments, engagement metrics, and detailed post analytics, with support for high-quality media downloads. Ideal for market research, content analysis, and trend monitoring.
Pricing
from $3.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
4
Bookmarked
93
Total users
13
Monthly active users
2 days ago
Last modified
Categories
Share
Lemon8 Scraper: Discovery Posts, Engagement, Comments & Media Links
Lemon8 Scraper turns Lemon8's keyword discovery feed into structured data. Search any keyword and region, or paste discovery links directly, and get post text, images, video links, author profiles, engagement counts, hashtags and full comment threads with nested replies. Export the dataset as JSON, CSV or Excel, or read it straight through the API.
Why This Scraper?
- Five ways to target content. Search by keyword and region, paste discovery or post links, crawl home-feed categories, or scrape an author's profile posts; each link's keyword and region are parsed automatically.
- Full post detail on demand. Turn on Get Detailed Post Data for untruncated post text, hashtags, related topics, edit history and real engagement counts.
- Complete comment threads. Expand every comment and its replies for a post, with a running total of comments and replies collected.
- 12 regional storefronts. United States, Australia, New Zealand, Japan, Thailand, Indonesia, Vietnam, Malaysia, Singapore, Canada, United Kingdom and Philippines (the site may serve little or nothing for some regions).
- Built for schedules. Incremental mode returns only new, updated and reappeared posts on recurring runs, and a run that could not read the discovery page fails loudly instead of quietly returning an empty dataset.
- Resume large pulls. Continue an interrupted run from its run or dataset ID to pick up where it left off.
- Send results onward. Pipe scraped posts into Notion, Linear, Airtable or Apify through MCP connectors.
Use Cases
- Content and trend research: track which topics, hashtags and post formats are performing on Lemon8 right now.
- Creator and influencer analysis: monitor a creator's posting cadence, engagement and comment sentiment over time.
- Brand and competitor monitoring: watch how a product, campaign or hashtag is discussed across regions.
- Regional market research: compare topic popularity for lifestyle, beauty or fashion content across storefronts.
- Dataset building: collect posts, images and comment threads for archives, reports or model training data.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
id | "7412987407534162437" |
title | "Weekend Outfit Ideas" |
content | "A quick roundup of what I wore this weekend..." (preview, truncated) |
postUrl | "https://www.lemon8-app.com/@sample_creator/7412987407534162437?region=us" |
author.name | "Sample Creator" |
author.profileUrl | "https://www.lemon8-app.com/@sample_creator?region=us" |
author.profileImageUrl | avatar image URL |
author.followerCount | null in search and feed rows (the listing card does not expose it); the real count in profile and post rows |
statistics.likesCount | "482" |
statistics.savedCount / statistics.commentsCount | "0" in search, feed and profile rows; the real counts are in details.statistics (see FAQ). Post-mode rows carry the real counts here too |
images | array of { src, alt } image URLs |
comments | [], reserved preview slot (see FAQ) |
isVideo | true or false |
videoData | poster image and type for video posts; the playable file appears under details.videoData |
searchQuery | "fashion" |
details.fullContent | untruncated post text, when Get Details is on |
details.hashtags | ["#fashion", "#ootd", "#weekendstyle"] |
details.editTime | "9/28" (month/day last edited) |
details.statistics | real savedCount / likesCount / commentsCount, when Get Details is on |
details.galleryImages | full resolution images, when Get Details is on |
details.relatedTopics | ["outfit ideas", "fall fashion"] |
allComments | full comment thread with nested replies, when Get Details is on |
commentStats | totalComments, totalReplies and previewCommentCount collected for the post |
In incremental mode, every record also carries changeType, changedFields, firstSeenAt and lastSeenAt (see How to Use).
Output views
The dataset has eight ready-made views in the Console: Posts Overview, Post Images, Video Posts, Content Creators, Post Comments, Detailed Post Content, Engagement Analytics and Incremental Changes (the change type and changed fields of each record, filled in incremental mode).
How to Use
- Pick how to target Lemon8: fill in Search Term and Region, or paste one or more links into Start URLs (Start URLs win when both are set).
- Set Post Limit, and turn on Get Detailed Post Data for full text, hashtags and comments, or leave it off for a faster shallow pass over the discovery feed.
- If you will run this actor on a schedule against the same search, turn on Incremental mode so later runs return only new and changed posts; otherwise leave that section alone.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
Search by keyword and region:
{"searchTerm": "skincare","region": "us","limit": 20,"getDetails": true}
Paste a discovery link instead:
{"searchTerm": "fashion","startUrls": ["https://www.lemon8-app.com/discover/coffee?region=jp"],"limit": 15}
Recurring monitoring of the same search:
{"searchTerm": "streetwear","region": "sg","limit": 50,"getDetails": false,"incrementalMode": true,"stateKey": "streetwear-sg-daily"}
Resume an interrupted run:
{"searchTerm": "travel","region": "au","limit": 200,"resumeFromRunId": "abcDEF123xyz"}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/lemon8-discover-scraper").call(run_input={"searchTerm": "fashion", "region": "us", "limit": 20})for post in client.dataset(run["defaultDatasetId"]).iterate_items():print(post["title"], post["statistics"]["likesCount"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/lemon8-discover-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) continues one interrupted run: paste its run or dataset ID to pick up where it left off. - Incremental mode (
incrementalMode) is for scheduling this actor against the same search. State is tracked bystateKey, or an automatic key derived from Search Term or Start URLs, Region and Get Detailed Post Data, so unrelated searches never share state. Each record is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEARED, orEXPIRED(only after a run that scanned every tracked target to its natural end, and only withemitExpired). A post isUPDATEDwhen any of its fields changes (title, text, hashtags, like and comment counts, comments, media); a re-signed or re-sharded image or video CDN address for the same file is never a change. The nestedauthor.followerCountis excluded from the comparison by default (the flatauthorFollowersis still compared). List fields inignoreFieldsForChanges(names or dot paths such asstatistics.likesCount) to exclude them from the comparison and fromchangedFields; they stay in the output, and changing the list does not re-flag posts you already track. With incremental mode off, output is exactly as before.
URL mode: supported link shapes
startUrls is pre-filled with five real examples (four search pages and one post page); profile pages are also accepted. In Scrape mode auto (and the other non-URL modes) the untouched example list is treated as "not supplied", so API calls and scheduled runs that never set startUrls keep searching by Search Term exactly as before. With Scrape mode url the list is always scraped as given, including the five examples. Change, add or remove any URL and URL mode is used instead of Search Term.
| Shape | Example | Result |
|---|---|---|
| Discover search with region | https://www.lemon8-app.com/discover/fashion?region=us | Posts for the keyword in that region |
| Experience search with region | https://www.lemon8-app.com/experience/coffee?region=us | Posts for the keyword on the experience page |
| Discover search, no region | https://www.lemon8-app.com/discover/nails | Uses the Region input (default US) |
| Multi-word keyword, other region | https://www.lemon8-app.com/discover/skin%20care?region=jp | Keyword "skin care" in Japan |
| Author profile page | https://www.lemon8-app.com/@janeddove?region=us | The author's posts, up to Post Limit (scraped as a profile target) |
| Single post page | https://www.lemon8-app.com/@janeddove/7460605475378283050?region=us | One post record with details and comments |
A ?page=N query parameter is ignored without a warning: the site serves page 1 whatever the value, so there is no URL pagination and page 1 of the keyword is scraped. Any other link (for example /hashtag/..., /search?q=... or a bare /discover) is skipped with a per-URL warning in the log.
Modes, feeds and profiles
Pick what to scrape with Scrape mode (default auto, the classic behaviour: Start URLs when edited, otherwise Search Term).
| Mode | Input used | Notes |
|---|---|---|
search | Keywords (several allowed) or Search Term | Post Limit applies per keyword. Several keywords are scraped one after another. |
url | Start URLs | Discovery, post and profile URLs. |
feed | Feed categories (foryou, food, beauty, fashion, home, fitness, health, relationship, travel, photography, pet, reading, cars, outdoors) | Home-feed posts per category, paged up to Post Limit. |
profile | Profile URLs (or @names) | An author's posts, paged up to Post Limit. |
post | Post URLs | One full record per post. |
Region now also accepts uk and ph (the site may serve little or nothing for a region; an empty region returns no rows, so no per-result charge; the per-run start fee still applies).
Every row also carries flat attribute fields next to the nested ones: groupId, url, articleClass, likes, saves, commentCount, authorUserId, authorUsername, authorNickname, authorAvatar, authorFollowers, videoUrl, thumbnailUrl, hashtags, topComments, keyword, category, region, sourceMode, scrapedAt. Saves and comment counts are filled when post details are on. authorFollowers is null in search and feed rows, like author.followerCount, and filled in profile and post rows.
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 |
|---|---|---|---|
mode | string | auto | auto, search, url, feed, profile or post (see Modes, feeds and profiles). |
keywords | array | (none) | Several keywords for search mode; Post Limit applies per keyword. |
feedCategories | array | (none) | Home-feed categories for feed mode. |
profileUrls | array | (none) | Author profile URLs or @names for profile mode. |
postUrls | array | (none) | Single post URLs for post mode. |
searchTerm | string | fashion | Keyword to search for on Lemon8. Used only when Start URLs is empty. |
startUrls | array | the five example URLs from the shape table | Lemon8 search pages and post pages to scrape instead of Search Term. Takes precedence over Search Term once you edit the list; in Scrape mode auto the untouched example list is ignored so a run that omits this field still searches by Search Term (mode url scrapes it as given). |
region | string | us | Target region: us, au, nz, jp, th, id, vn, my, sg, ca, uk or ph. |
limit | integer | 2 | Maximum number of posts to extract per target (1 to 5000). |
getDetails | boolean | true | Navigate to each post's page for full content, hashtags, related topics and all comments. |
detailsLimit | integer | 2 | Maximum number of posts, out of Post Limit, to fetch detailed data for (1 to 3000). |
commentExpansionTimeout | integer | 30 | Seconds to spend expanding one post's comments before moving on (10 to 300). |
resumeFromRunId | string | (none) | Continue one interrupted run or dataset, picking up where it left off. |
incrementalMode | boolean | false | Turn on for recurring runs: classify each post as NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED against the previous run. |
stateKey | string | (none) | Name or share an incremental-mode monitoring campaign; otherwise a key is derived automatically from the search scope. |
emitUnchanged | boolean | false | Also return (and bill) UNCHANGED posts every run. |
emitExpired | boolean | false | Also return (and bill) posts no longer found, once a run fully scans every tracked target. |
ignoreFieldsForChanges | array | [] | Incremental mode only: field names or dot paths excluded from change detection (kept in the output). |
saveImages | boolean | false | Reserved; has no effect in the current version. Image links are always returned in images (and details.galleryImages when Get Detailed Post Data is on). |
saveVideos | boolean | false | Reserved; has no effect in the current version. The playable video link is returned in details.videoData.videoUrl when Get Detailed Post Data is on. |
proxy | object | prefill: Apify Proxy (US) | Connection settings. Defaults to the Apify datacenter pool (US). Left completely empty (for example, via a bare API call), the actor connects directly. |
dev_transform_fields | array | [] | Return only the listed fields per post. Use a dot path for nested objects and a numeric index for arrays. |
dev_dataset_name | string | default | Save results into a custom named dataset instead of the default one. Supports {ACTOR}, {DATE} and {TIME} masks. |
dev_dataset_clear | boolean | false | Clear the target dataset before this run inserts new items. |
mcpConnectors | array | (none) | Optional: send a summary of each post to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which post pages are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"id": "7412987407534162437","author": {"name": "Sample Creator","followerCount": null,"profileUrl": "https://www.lemon8-app.com/@sample_creator?region=us","profileImageUrl": "https://p16-sign-va.tiktokcdn.com/sample-avatar.jpg"},"title": "Weekend Outfit Ideas","content": "A quick roundup of what I wore this weekend, from brunch to a night out...","postUrl": "https://www.lemon8-app.com/@sample_creator/7412987407534162437?region=us","statistics": {"savedCount": "0","likesCount": "482","commentsCount": "0"},"images": [{ "src": "https://p16-sign-va.tiktokcdn.com/sample-image-1.jpg", "alt": "" },{ "src": "https://p16-sign-va.tiktokcdn.com/sample-image-2.jpg", "alt": "" }],"comments": [],"isVideo": false,"videoData": null,"searchQuery": "fashion","details": {"title": "Weekend Outfit Ideas","fullContent": "A quick roundup of what I wore this weekend, from brunch to a night out. Full untruncated post text goes here.","hashtags": ["#fashion", "#ootd", "#weekendstyle"],"editTime": "9/28","statistics": {"savedCount": "312","likesCount": "482","commentsCount": "37"},"galleryImages": [{ "src": "https://p16-sign-va.tiktokcdn.com/sample-image-1.jpg", "alt": "" },{ "src": "https://p16-sign-va.tiktokcdn.com/sample-image-2.jpg", "alt": "" }],"searchQuery": null,"relatedTopics": ["outfit ideas", "fall fashion"],"isVideo": false,"videoData": null},"allComments": [{"author": "Sample Commenter","authorTag": null,"content": "Love this look!","time": "9/27","likes": "12","replies": [{ "author": "Sample Creator", "content": "Thank you!", "time": "9/27", "tag": null }]}],"commentStats": {"totalComments": 37,"totalReplies": 9,"previewCommentCount": 0}}
Plan Requirement
The default connection setting (Apify datacenter proxy, US exit) is enough for Lemon8's discovery, experience and post pages; no residential proxy is required. This was measured from a hosting-provider (datacenter-class) address rather than through Apify's own proxy pool: the pages loaded with HTTP 200, and the only refusal seen was a single HTTP 403 on a repeated author-profile fetch, so profile mode may be less stable than the other modes.
An Apify free plan does not include Apify Proxy at all. On a free plan the run logs "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable." and tries a backup connection, which may not load every page. If nothing loads, the run fails with "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Lemon8 pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again." On a paid plan whose proxy access is refused outright, the failure reads "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required". If the pages simply fail to load you get "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search." A paid plan or your own proxy URLs avoid all of these.
FAQ
How much does it cost?
You pay per record returned plus a small start fee per run. On the Apify Free plan that is $0.003 per result and $0.15 per run start (about $3.15 per 1,000 results); other plans have their own rates on the Pricing tab, which is the authority. Posts suppressed as unchanged in incremental mode are not returned or billed. Use Post Limit and Details Post Limit to cap the cost of any run.
Is it legal to scrape Lemon8?
This actor collects only publicly available discovery-feed data. You are responsible for how you use it: follow Lemon8's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Post text and counts are generally facts, but images, video and profile photos may be subject to third-party rights.
Is there a cap on comments per post?
No fixed count. With Get Detailed Post Data on, the actor expands the comment thread and replies for up to Details Post Limit posts, spending at most Comment Expansion Timeout seconds per post; a very large thread can be cut short by that timeout.
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, updated and reappeared posts, and unchanged ones are not returned or billed unless you turn on Emit unchanged.
Why do a post's saved and comment counts show 0?
The discovery feed itself only reports a like count, so statistics.savedCount and statistics.commentsCount are "0" at the top level of search, feed and profile rows (post-mode rows already carry the real counts there). Turn on Get Detailed Post Data and the real saved, like and comment counts appear in details.statistics for each detailed post (up to Details Post Limit).
Why did my run fail instead of returning an empty dataset?
If Start URLs is set but none of its entries is a recognizable Lemon8 discovery link, or if every request to the discovery page was refused or timed out, the run fails with a specific, actionable message and no dataset item is billed (the per-run start fee still applies). A search or region that genuinely has no matching posts is a different case: the run still succeeds, and simply returns nothing.
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 Media Scraper Lightweight Lemon8 scraper for extracting image and video URLs from posts, with optional... | π± Truth Social Scraper Scrape public Truth Social profiles, posts, media, metrics, author data, and complete... |
| π± Redditβ‘ Lightning From $1/1K. Scrape Reddit posts, comments, and media from any subreddit or user profile -... | π Lazada Scraper Scrape Lazada products and reviews across SEA markets, including Malaysia, Singapore... |
π 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.