X Twitter Scraper - Tweets, Profiles, Views & Engagement avatar

X Twitter Scraper - Tweets, Profiles, Views & Engagement

Pricing

from $1.00 / 1,000 actor run starteds

Go to Apify Store
X Twitter Scraper - Tweets, Profiles, Views & Engagement

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

SR

Maintained by Community

Actor stats

0

Bookmarked

8

Total users

5

Monthly active users

3 days ago

Last modified

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, and created_at
  • like_count, retweet_count, reply_count, quote_count, bookmark_count and view_count
  • is_retweet and is_quote, so reposts can be separated from original posts in one filter
  • conversation_id, which lets replies be grouped back into threads
  • hashtags, mentions, links and media_urls
  • lang, username, user_id, user_followers, user_is_verified and a direct url
  • tweet_id, source_target (the handle, ID or term that produced the row), discovery, profile_followers and position

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

fieldwhat it doesdefault
targetsHandles or post IDs: nasa, @openai, or a numeric ID—
search_termsSearch terms, e.g. web scraping, nasa artemis—
tweets_per_termMaximum posts per search term30
search_pagesSearch pages per term2
tweets_per_userMaximum posts per account; 0 for profiles only40
max_targetsMaximum targets50
concurrencyTargets in parallel3
retriesRetries per request3
countryRequest from country, optionally—
authorOnly posts by this account—
mentioningOnly posts mentioning this account—
tweetLanguagePost language, e.g. en—
minimumFavoritesMinimum likes—
minimumRetweetsMinimum reposts—
minimumRepliesMinimum replies—
start / endDate range, as YYYY-MM-DD—
onlyImage / onlyVideo / onlyQuoteOnly posts with images, with video, or quote postsfalse
onlyVerifiedUsersOnly verified accountsfalse
maxItemsHard 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:

operatorhow 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 actorsigned-in search scrapersofficial X API
Login, cookies or keynonean account or sessiona developer key
Account timelines with viewsyesyesyes, by tier
Searchvia a public index, older postsX's own search, Top/Latestyes, by tier
Advanced-search operatorsparsed, unsupported ones reportedvariesyes
Price$1.50 per 1,000 postsvariesreading 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.