Twitter scraper: scrape X without the official API.
Tweets, profiles, followers, trends and more.
Both give you the same data. Hosted: you press a button and get the results. Self-hosted: you run the code, and you manage the accounts and the proxies.
Runs on Apify. You do not need X accounts, cookies or proxies.
- Configure and run from your browser, no code needed, or drive it from code with the Python API
- Search tweets, profile timelines, follower / following lists
- Monitor accounts, a brand or a token on a schedule, with no server to run
- Export in different formats (JSON, CSV or XLSX)
- Free tier included; pay-as-you-go pricing is on the Actor page
Bring your own X accounts and proxies. Run it from Python or the CLI, inside your own infrastructure.
from Scweet import Scweet
s = Scweet(auth_token="YOUR_AUTH_TOKEN")
tweets = s.search("bitcoin", limit=100)Scweet works with any proxy. A proxy is optional for a small run and recommended for real volume, because many requests from one IP raise the risk to an account. Put the values of your proxy in place of each value that starts with YOUR_:
s = Scweet(auth_token="YOUR_AUTH_TOKEN",
proxy="http://YOUR_LOGIN:YOUR_PASSWORD@YOUR_HOST:YOUR_PORT")With several accounts or a rotating proxy, see Multiple accounts & proxies.
Our proxy sponsor, Proxy-Seller, gives 15% off residential, ISP and IPv4 proxies with the code SCWEET.
- Tweets — by keyword, hashtag, user, date range, engagement filters, language, location
- Profile timelines — a user's full tweet history, with replies and media tabs
- Tweets by id — full data for known tweet ids, their replies, and who reposted them
- Followers / Following — full account lists at scale, verified followers included
- User profiles — bio, follower count, verification status, by handle or by id
- People search & trends — find accounts by keyword, read what is trending now
Three steps from nothing to tweets. One account, one call, one result.
1. Install
pip install -U Scweet2. Get your auth_token
Log into x.com → DevTools F12 → Application → Cookies → https://x.com → copy the auth_token value. That one value is all you need; Scweet builds the rest.
Use a dedicated account, never your personal one.
3. Scrape
from Scweet import Scweet
s = Scweet(auth_token="YOUR_AUTH_TOKEN")
tweets = s.search("bitcoin", limit=100)
for tweet in tweets:
print(tweet["text"])That is the whole first run. On the next run, reuse the same accounts with no credentials:
s = Scweet() # reads the state file scweet_state.db
tweets = s.search("ethereum", limit=100, save=True) # save=True writes a CSVAlways set
limit. Without it, a run continues until the daily cap of the account.
Next: add proxies and several accounts for real volume, or read the full documentation.
All methods have async variants:
asearch(),aget_profile_tweets(),aget_followers(), etc.
tweets = s.search(
"AI agents",
since="2026-01-01",
from_users=["elonmusk"],
min_likes=50,
limit=200,
save=True,
)tweets = s.get_profile_tweets(["elonmusk"], limit=200)followers = s.get_followers(["elonmusk"], limit=1000)
following = s.get_following(["elonmusk"], limit=1000)
verified = s.get_verified_followers(["elonmusk"], limit=1000)profiles = s.get_user_info(["githubstatus", "elonmusk"])
profiles = s.get_user_info(user_ids=["44196397"]) # numeric ids work tootweets = s.get_tweet_info(["1866123456789", "1866123456790"]) # up to 50 per request
replies = s.get_tweet_replies("1866123456789", limit=100)
reposters = s.get_reposters("1866123456789", limit=100)people = s.search_users("python developer", limit=50)
trends = s.get_trending()
media = s.get_profile_media(["nasa"], limit=100)
tweets = s.get_profile_tweets(["nasa"], limit=100, include_replies=True)For the full list of supported search operators, see twitter-advanced-search.
# Search with proxy, save to CSV
scweet --auth-token YOUR_AUTH_TOKEN --proxy http://YOUR_LOGIN:YOUR_PASSWORD@YOUR_HOST:YOUR_PORT \
search "bitcoin" --since 2026-01-01 --limit 500 --save
# Followers, saved as JSON
scweet --auth-token YOUR_AUTH_TOKEN \
followers elonmusk --limit 1000 --save --save-format jsonFor multi-account runs, use --cookies-file cookies.json.
For higher throughput and reduced ban risk, use several dedicated accounts. List them in cookies.json, and replace each value that starts with YOUR_.
A fixed proxy for each account, for example datacenter or ISP proxies:
[
{ "username": "acct1", "cookies": { "auth_token": "YOUR_AUTH_TOKEN_1" },
"proxy": "http://YOUR_LOGIN:YOUR_PASSWORD@YOUR_HOST_1:YOUR_PORT" },
{ "username": "acct2", "cookies": { "auth_token": "YOUR_AUTH_TOKEN_2" },
"proxy": "http://YOUR_LOGIN:YOUR_PASSWORD@YOUR_HOST_2:YOUR_PORT" }
]s = Scweet(cookies_file="cookies.json") # proxies are read from the file, one per accountOne rotating proxy for all accounts, for example residential proxies. Leave "proxy" out of cookies.json, and put {session} where your provider names a sticky session. Keep {session} exactly as it is:
s = Scweet(cookies_file="cookies.json",
proxy="http://YOUR_LOGIN-session-{session}:YOUR_PASSWORD@YOUR_HOST:YOUR_PORT")Scweet replaces {session} with the name of the account and 8 random characters, for example YOUR_LOGIN-session-acct1a3f9c2b7 for acct1. Each account therefore keeps its own IP, and a request that fails in the network retries from a new IP. Each provider writes the session in its own way: read Proxy modes.
Never use your personal Twitter/X account for scraping. Use dedicated accounts only.
One page of X is easy to fetch. 10,000 tweets is not, because accounts get rate-limited, cookies expire, and X changes its API.
Your run finishes
- A wide date range is split into intervals that run in parallel. If X stops one interval early, the others still fill.
- If X ends a page chain early, Scweet continues from the oldest tweet it received.
- If a run stops,
resume=Truecontinues from the last saved point instead of starting again.
Your accounts stay usable
- Scweet reads the rate-limit headers of X and stops each account 2 requests before its limit, so X does not block it.
- Scweet identifies the cause of each error. A bad request, an old query id and a dead session are handled differently, so a small error does not cost you an account.
- Scweet records the state of each account (locked, suspended, rate-limited) and waits the needed time before it uses that account again.
It keeps working when X changes
- X changes the ids of its internal API without notice. Scweet reads the new ids from the JavaScript files of X, at startup or when you call
refresh_manifest().
It is easy to work with
- 12 read operations, one consistent row shape, sync and async, a real CLI, and CSV/JSON output built in.
- 25 fields per tweet, including view counts, quotes, bookmarks, language and the nested quoted or retweeted post.
Or let us run it for you
- The hosted version does all of the above on our accounts and proxies. Free trial included.
Also on twint and snscrape: both are unmaintained and no longer work against X's current backend. If you are migrating from either, Scweet covers the same ground and more.
- Only publicly visible content is accessible — private/protected accounts are not supported
- Relies on undocumented X web endpoints; breakage is always possible after platform changes. Scweet self-heals by scraping fresh query IDs and feature flags from X's own bundles — at startup with
manifest_scrape_on_init=True, or on demand at any time:s = Scweet(auth_token="...", manifest_scrape_on_init=True) changes = s.refresh_manifest() # or: scweet refresh-manifest
- Cookies can expire and may need periodic refreshing
- A single account typically handles hundreds to a few thousand tweets per day before hitting rate limits; multi-account pooling scales proportionally
- Proxies and dedicated accounts are strongly recommended for anything beyond light testing
- Username/password login is not supported. X's anti-automation defenses make programmatic login unreliable and likely to trigger account locks. Scweet authenticates with browser cookies (
auth_token) extracted from an active session instead
Full API reference, config options, structured search filters, async patterns, resume, proxies, and troubleshooting.
Read it as a site: altimis.github.io/Scweet — the same text, with search and a navigation menu.
- Account setup
- Search API
- Profile tweets
- Tweet lookup & replies
- Followers / Following
- User info
- Search users & trends
- Manifest refresh
- Saving results
- Resume interrupted searches
- Controlling limits
- Configuration reference
- Account management (ScweetDB)
- Async usage
- Error handling
- CLI reference
For advanced Twitter search operators, see twitter-advanced-search.
FAQ
Does it work without an official Twitter API key? Yes. Scweet calls X's internal GraphQL API — the same one the web app uses. No developer account or API key required.
Is it a replacement for twint or snscrape? Yes. Both are broken as of 2024–2025. Scweet uses a different, currently-working approach: cookies + GraphQL instead of legacy unauthenticated endpoints.
How many tweets can I scrape? A single account typically handles hundreds to a few thousand tweets per day before hitting rate limits. Multi-account pooling scales this proportionally. The hosted Apify actor manages accounts and rate limits automatically.
Will my account get banned? Never use your personal account — use dedicated accounts only. To reduce risk further: use multiple accounts (distributes load) and pair each with a proxy (prevents all requests from one IP).
Does it work for private accounts? No. Only publicly visible content is accessible.
Does it still work in 2025 / 2026? Yes — last verified with the 5.8.2 release (2026-10-22) against X's current GraphQL API.
Have a question or want to share what you built with Scweet? Open a thread in GitHub Discussions.
Found it useful? Star the repo
Bug reports, feature suggestions, and PRs are welcome. See CONTRIBUTING.md.
MIT License

