X Twitter Scraper - Tweets, Profiles, Views & Engagement
Pricing
from $1.00 / 1,000 actor run starteds
X Twitter Scraper - Tweets, Profiles, Views & Engagement
Scrape X (Twitter) by handle, post ID or search term, with X's own advanced-search operators. Returns profiles with follower counts and posts with likes, reposts, replies, quotes, bookmarks and view counts. No login, cookies or API key.
Pricing
from $1.00 / 1,000 actor run starteds
Rating
0.0
(0)
Developer
SR
Maintained by CommunityActor stats
0
Bookmarked
8
Total users
5
Monthly active users
3 days ago
Last modified
Categories
Share
X Twitter Scraper: Tweets, Profiles and View Counts
This Twitter scraper reads X (formerly Twitter) three ways: by handle, by post ID, or by search term. Use it to track accounts, benchmark engagement or hydrate post IDs you already have. You get the full profile with follower counts, plus posts carrying likes, reposts, replies, quotes, bookmarks and view counts.
No login, no cookies, no API key.
What the Twitter scraper returns
Per account, in the run summary: follower count, following count, total posts, bio, location, join date, verification, profile and banner images.
Per post, one row each:
text, untruncated, andcreated_atlike_count,retweet_count,reply_count,quote_count,bookmark_countandview_countis_retweetandis_quote, so reposts can be separated from original posts in one filterconversation_id, which lets replies be grouped back into threadshashtags,mentions,linksandmedia_urlslang,username,user_id,user_followers,user_is_verifiedand a directurltweet_id,source_target(the handle, ID or term that produced the row),discovery,profile_followersandposition
View counts are the one most people are surprised to get: X publishes them on posts but not on every surface, and they come through here.
Input
| field | what it does | default |
|---|---|---|
targets | Handles or post IDs: nasa, @openai, or a numeric ID | — |
search_terms | Search terms, e.g. web scraping, nasa artemis | — |
tweets_per_term | Maximum posts per search term | 30 |
search_pages | Search pages per term | 2 |
tweets_per_user | Maximum posts per account; 0 for profiles only | 40 |
max_targets | Maximum targets | 50 |
concurrency | Targets in parallel | 3 |
retries | Retries per request | 3 |
country | Request from country, optionally | — |
author | Only posts by this account | — |
mentioning | Only posts mentioning this account | — |
tweetLanguage | Post language, e.g. en | — |
minimumFavorites | Minimum likes | — |
minimumRetweets | Minimum reposts | — |
minimumReplies | Minimum replies | — |
start / end | Date range, as YYYY-MM-DD | — |
onlyImage / onlyVideo / onlyQuote | Only posts with images, with video, or quote posts | false |
onlyVerifiedUsers | Only verified accounts | false |
maxItems | Hard cap on rows for the whole run, applied after every filter | — |
Handles and search terms can be mixed in the same run; they are separate
fields so an ambiguous word like apify is never guessed at.
tweets_per_user set to 0 turns each account into a single request: three
accounts came back in about five seconds that way, against ten for the same
three at forty posts each.
Keep parallelism modest. Each account is a profile lookup followed by several sequential page requests, so concurrency multiplies quickly.
Advanced-search operators
X's own search syntax works as input, the one documented at
igorbrigadir/twitter-advanced-search. Paste a query you already use and it is
parsed rather than treated as literal words.
Honoured, and how:
| operator | how it is served |
|---|---|
from: | routed — that account's timeline is read directly, which is better data than finding the same posts by search |
lang: since: until: since_time: until_time: | applied to the results |
min_faves: min_retweets: min_replies: | applied to the results |
conversation_id: url: | applied to the results |
filter: / -filter: / exclude: | images, videos, media, quote, links, replies, nativeretweets |
Not honoured, and reported rather than dropped: the geo family (geocode:
near: within: place:) because no row carries coordinates; the card family
and source: because those fields are not published on the surfaces read here;
list: because list timelines need a signed-in session; and to:
quoted_tweet_id: quoted_user_id: max_id: since_id:.
If you pass one of those, the run summary lists it under operatorsIgnored
with a note saying the results are wider than your query asked for. An
operator that vanishes quietly gives you rows you believe were filtered.
The form fields above (author, language, minimum likes, date range, only-images and so on) are the same vocabulary as the operators and can be mixed; an operator written in a term beats a form field of the same name.
Output example
One real row from a run with targets: ["nasa", "openai"] and
search_terms: ["web scraping"] (the default prefill), taken from NASA's
timeline:
{"tweet_id": "2105842656429432894","url": "https://x.com/NASA/status/2105842656429432894","text": "Welcome aboard! 🙌\n\nAfter nearly eight hours in flight, Crew-13 arrived at the @Space_Station, where they will spend the next several months conducting experiments on science and tech to benefit life on Earth and in space. https://t.co/2bTqsLFWa6","created_at": "Fri Oct 02 02:09:48 +0000 2026","lang": "en","like_count": 6822,"retweet_count": 866,"reply_count": 192,"quote_count": 63,"bookmark_count": 218,"view_count": 582720,"is_retweet": false,"is_quote": false,"conversation_id": "2105842656429432894","username": "NASA","user_id": "11348282","user_followers": 92377141,"user_is_verified": true,"hashtags": null,"mentions": ["Space_Station"],"links": null,"media_urls": ["https://pbs.twimg.com/amplify_video_thumb/2105842619867656192/img/RLtky5UmWy8qAhZd.jpg"],"source_target": "nasa","discovery": "x-timeline","profile_followers": 92377212,"position": 1}
That same run returned 84 posts, two profiles (NASA with 92,377,212 followers, OpenAI with 5,411,571) and four posts found through the search term.
Run summary
Targets requested, profiles found (profiles, with the fields listed above),
posts returned, protected accounts, total likes and total views across
everything collected, how many posts were reposts rather than original, and the
search figures tweetsDiscoveredBySearch and searchHydrationRate.
How Twitter search works here
X refuses its own search to anyone who is not signed in. So a search term is a two-step: a public search engine (Yahoo) supplies the URLs of posts matching your phrase, and then each post is read from X itself. There is no API key to obtain and no metered service in the middle.
- The data is first-hand. Likes, reposts, views and text all come from X at the moment of the run, not from a cached search snippet.
- The discovery is second-hand. You get posts a search engine has indexed, which skews toward posts that have been public for a while. Something posted in the last hour will usually not appear.
Every row records which it was in the discovery field: x-timeline,
tweet-id or search-engine. A search index outlives deleted posts, so
searchHydrationRate (the share of discovered posts that still resolved) is
rarely 100%; a typical run lands between 60% and 100%. Seeing that number is
better than quietly getting fewer rows than you asked for.
Fetching single posts
A target made only of digits is treated as a post ID rather than a handle, which is unambiguous because X handles cannot be all digits. That is well suited to bulk hydration: give it a list of IDs you already have and it fills in the text and engagement for each.
Fewer fields come back that way (reposts, quotes, bookmarks and views are not published on that surface), which the empty columns will show you honestly.
Protected accounts
A protected account returns its profile and no posts. That is the account's own setting, not a failure: the profile appears in the summary and the handle is listed under protected accounts rather than under errors.
Use cases
Competitor and brand monitoring. Follower counts alongside per-post engagement, collected on a schedule, show both audience growth and what actually lands.
Engagement benchmarking. Because view counts come through, engagement can be measured as a rate rather than as a raw like count, which is the only version of that number that compares across accounts of different sizes.
Thread reconstruction. conversation_id groups a thread back together
from the posts you collected.
Bulk post hydration. If you already have post IDs from somewhere else, feeding them in fills in text and engagement for each.
Follower tracking. Set tweets_per_user to 0 and schedule the run to
record follower and post counts across a long list of accounts.
How this compares to other Twitter scrapers
| this actor | signed-in search scrapers | official X API | |
|---|---|---|---|
| Login, cookies or key | none | an account or session | a developer key |
| Account timelines with views | yes | yes | yes, by tier |
| Search | via a public index, older posts | X's own search, Top/Latest | yes, by tier |
| Advanced-search operators | parsed, unsupported ones reported | varies | yes |
| Price | $1.50 per 1,000 posts | varies | reading needs a paid tier |
Some actors on the Store reach 30 to 80 posts per second and offer Top/Latest sorting by driving X's own search with signed-in sessions. This one reads what a signed-out visitor can see, so search is slower and has no sort control. Where it is competitive: reading named accounts, where the timeline gives full first-hand data, and applying the filters above to whatever it collects.
Scale and cost
A profile lookup is one request. Each page of posts is another and returns about 20, so an account at 40 posts costs three requests in total. Two accounts at 40 posts each returned 81 rows in 46 seconds in testing, including one target that did not exist and was reported as an error.
Nothing needs configuring and nothing needs to be kept alive between runs.
FAQ
Do I need a Twitter/X account, cookies or an API key? No. Everything is what a signed-out visitor can see: public accounts, public posts, public counts.
Why do two runs a few minutes apart show different numbers? Engagement moves quickly on fresh posts. That difference is the data rather than an error.
Why do reposts show zero likes?
Reposts appear as rows with is_retweet true and, typically, zero likes of
their own: the engagement sits on the original post. Filter on that flag rather
than treating those as underperforming posts.
What happens with deleted posts or suspended accounts? They return nothing and are reported as errors naming the target, not dropped silently. If X changes the endpoint this reads, every target fails at once; that is reported as its own error and flagged in the run summary, so a failed run tells you whether the problem is your input or ours.
Can the same post appear twice? Rows are deduplicated by post ID within each account timeline. A post requested through more than one target or search term can appear more than once.
Can I get only profiles, without posts?
Yes: set tweets_per_user to 0. Profiles land in the run summary and no post
rows are charged.
Pricing
Each run has a $0.001 start fee. Each post delivered to the dataset costs
$0.0015, so 1,000 posts cost $1.50. Empty results incur no post charge.
Profiles are included in the run summary; setting tweets_per_user to 0
produces no billable post rows.
Users without a paid Apify plan receive at most 10 post rows per run. Paying users keep their requested limits. Existing input names and defaults continue to work, including the profile-only setting.