Metadata-Version: 2.4
Name: Scweet
Version: 5.7.0
Summary: Scrape tweets, profiles, followers and more from Twitter/X — no API key needed
Home-page: https://github.com/Altimis/Scweet
Download-URL: https://github.com/Altimis/Scweet/archive/v5.7.0.tar.gz
Author: Yassine AIT JEDDI
Author-email: aitjeddiyassine@gmail.com
License: MIT
Keywords: twitter,x,scraper,twitter-scraper,x-scraper,tweets,tweet-search,twitter-search,followers,following,twitter-api-alternative,graphql,web-scraping,social-media,data-collection,python
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: python-dotenv
Requires-Dist: sqlmodel>=0.0.22
Requires-Dist: SQLAlchemy>=2.0
Requires-Dist: curl_cffi
Requires-Dist: beautifulsoup4
Requires-Dist: XClientTransaction>=1.0.2
Requires-Dist: pydantic>=2.0
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: download-url
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

<p align="center">
  <img src="assets/scweet_banner.png" alt="Scweet" width="480" />
</p>

<p align="center">
  <strong>Scrape Twitter / X without the official API.</strong>
  <br>
  Hosted on Apify with no cookies or proxies, or run locally with Python and CLI.
</p>

<p align="center">
  <a href="https://apify.com/altimis/scweet?fpr=a40q9">
    <img alt="Run on Apify" src="https://img.shields.io/badge/Run%20on-Apify-246DFF?logo=apify&logoColor=white">
  </a>
  <a href="#python-quickstart">
    <img alt="Python Quickstart" src="https://img.shields.io/badge/Python-Quickstart-3776AB?logo=python&logoColor=white">
  </a>
  <a href="#cli">
    <img alt="CLI Quickstart" src="https://img.shields.io/badge/CLI-Quickstart-111111?logo=gnu-bash&logoColor=white">
  </a>
  <a href="#documentation">
    <img alt="Documentation" src="https://img.shields.io/badge/Docs-Full%20Reference-0A66C2">
  </a>
</p>

<p align="center">
  <a href="https://github.com/Altimis/Scweet/actions/workflows/tests.yml">
    <img alt="Tests" src="https://github.com/Altimis/Scweet/actions/workflows/tests.yml/badge.svg">
  </a>
  <a href="https://pypi.org/project/scweet/">
    <img alt="PyPI Version" src="https://img.shields.io/pypi/v/scweet.svg">
  </a>
  <a href="https://pepy.tech/projects/scweet">
    <img alt="PyPI Downloads" src="https://static.pepy.tech/badge/scweet/month">
  </a>
  <a href="https://github.com/Altimis/Scweet/blob/master/LICENSE.txt">
    <img alt="License" src="https://img.shields.io/github/license/Altimis/scweet">
  </a>
  <a href="https://apify.com/altimis/scweet">
    <img alt="Scweet Actor Status" src="https://apify.com/actor-badge?actor=altimis/scweet">
  </a>
</p>


---
<p align="center">
<strong>Scrape tweets, profile timelines, followers and more from Twitter/X. Use the hosted Apify Actor when you do not want to manage cookies or proxies, or run locally with your own browser cookies and account pool.</strong>
</p>

---

**What you can scrape:**
- [**Tweets**](DOCUMENTATION.md#search-api) — by keyword, hashtag, user, date range, engagement filters, language, location
- [**Profile timelines**](DOCUMENTATION.md#profile-tweets) — a user's full tweet history, with replies and media tabs
- [**Tweets by id**](DOCUMENTATION.md#tweet-lookup--replies) — full data for known tweet ids, their replies, and who reposted them
- [**Followers / Following**](DOCUMENTATION.md#followers--following) — full account lists at scale, verified followers included
- [**User profiles**](DOCUMENTATION.md#user-info) — bio, follower count, verification status, by handle or by id
- [**People search & trends**](DOCUMENTATION.md#search-users) — find accounts by keyword, read what is trending now

---

## Hosted alternative — no setup needed

<table>
<tr>
<td>

<p>
Use the hosted Apify Actor when you want Scweet results without running the local Python library or managing Twitter/X cookies, proxies, local accounts, rate limits, retries, or infrastructure.
</p>

<p>
This runs on Apify instead of your machine. Use the local library below when you want full Python/CLI control.
</p>

<p align="center">
  <a href="https://apify.com/altimis/scweet?fpr=a40q9&fp_sid=jeb97">
    <img alt="Run Scweet on Apify" src="https://img.shields.io/badge/Run%20Scweet%20on-Apify-246DFF?style=for-the-badge&logo=apify&logoColor=white">
  </a>
</p>

<ul>
  <li>No code required: configure and run from the Apify Console</li>
  <li>Prefer code? Use the Actor through Apify's <a href="https://apify.com/altimis/scweet/api/python">Python API guide</a></li>
  <li>No Twitter/X cookies or proxies to provide</li>
  <li>Search tweets, profile timelines, and follower / following lists</li>
  <li>Export results as JSON, CSV, or XLSX from the Apify dataset</li>
  <li>Free tier included; current usage pricing is shown on the Apify Actor page</li>
</ul>

</td>
</tr>
</table>

---

## Python Quickstart

Use local Scweet when you want full control from Python or the CLI, with your own browser cookies, accounts, proxies, SQLite state, resume behavior, and output files.

**1. Install**

```bash
pip install -U Scweet
```

**2. Get your `auth_token`**

Log into [x.com](https://x.com) → DevTools `F12` → **Application** → **Cookies** → `https://x.com` → copy the `auth_token` value.

Scweet auto-bootstraps the `ct0` CSRF token from `auth_token` alone — or use the [`cookies.json` format](#multiple-accounts--proxies) for multiple accounts at once.

**3. Scrape**

```python
from Scweet import Scweet

# Credentials are stored in scweet_state.db automatically on first run.
# A proxy is recommended. {session} gives each account its own proxy session on a rotating provider.
s = Scweet(auth_token="YOUR_AUTH_TOKEN", proxy="http://user,session-{session}:pass@host:port")

# Search tweets — save to CSV (save_format="json" or "both" also works)
tweets = s.search("bitcoin", since="2026-01-01", limit=500, save=True)

# Reuse provisioned accounts on subsequent runs — no credentials needed
s = Scweet(db_path="scweet_state.db")
tweets = s.search("ethereum", limit=500, save=True)
```

> Always set `limit` — without it, scraping continues until your account's daily cap is hit.

> All methods have async variants: `asearch()`, `aget_profile_tweets()`, `aget_followers()`, etc.

---

## Common tasks

### Search tweets

```python
tweets = s.search(
    "AI agents",
    since="2026-01-01",
    from_users=["elonmusk"],
    min_likes=50,
    limit=200,
    save=True,
)
```

### Profile timeline

```python
tweets = s.get_profile_tweets(["elonmusk"], limit=200)
```

### Followers / Following

```python
followers = s.get_followers(["elonmusk"], limit=1000)
following = s.get_following(["elonmusk"], limit=1000)
verified  = s.get_verified_followers(["elonmusk"], limit=1000)
```

### User profiles

```python
profiles = s.get_user_info(["githubstatus", "elonmusk"])
profiles = s.get_user_info(user_ids=["44196397"])   # numeric ids work too
```

### Tweets by id, replies, reposters

```python
tweets    = 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 search, trends, media

```python
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](https://github.com/igorbrigadir/twitter-advanced-search).

---

## CLI

```bash
# Search with proxy, save to CSV
scweet --auth-token YOUR_AUTH_TOKEN --proxy http://user:pass@host: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 json
```

For multi-account runs, use `--cookies-file cookies.json`.

---

## Multiple accounts & proxies

For higher throughput and reduced ban risk, use multiple dedicated accounts with per-account proxies.

Running Scweet locally at any real volume usually means dedicated accounts and proxies. You can use a single proxy, a rotating proxy, or assign one per account. On a rotating provider, put `{session}` in the proxy URL to give each account its own session — see "Proxy modes" in DOCUMENTATION.md.

**`cookies.json` format:**

```json
[
  { "username": "acct1", "cookies": { "auth_token": "..." }, "proxy": "http://user1:pass1@host1:port1" },
  { "username": "acct2", "cookies": { "auth_token": "..." }, "proxy": "http://user2:pass2@host2:port2" }
]
```

```python
s = Scweet(cookies_file="cookies.json")  # proxies are read from the file, one per account
```

> **Never use your personal Twitter/X account for scraping.** Use dedicated accounts only.

---

## Why Scweet?

| | twint | snscrape | twscrape | **Scweet** |
|---|---|---|---|---|
| **Works in 2026** | ❌ unmaintained | ❌ broken | ✅ | ✅ |
| Cookie / token auth | ❌ | ❌ | ✅ | ✅ |
| Multi-account pooling | ❌ | ❌ | ✅ | ✅ |
| Proxy support | ❌ | ❌ | ✅ | ✅ |
| Resume interrupted scrapes | ❌ | ❌ | ❌ | ✅ |
| Built-in CSV / JSON output | ✅ | ✅ | ❌ | ✅ |
| Sync + async API | ❌ | ❌ | Async only | ✅ both |
| Hosted, no-setup option | ❌ | ❌ | ❌ | ✅ Apify |
| Active maintenance | ❌ | ❌ | ⚠️ | ✅ |

[twint](https://github.com/twintproject/twint) has been unmaintained since 2023. [snscrape](https://github.com/JustAnotherArchivist/snscrape) broke after X's backend changes. [twscrape](https://github.com/vladkens/twscrape) is the closest active alternative — worth knowing, but async-only, no built-in file output, and no resume support.

---

## Limitations

- 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:
  ```python
  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

---

## Documentation

Full API reference, config options, structured search filters, async patterns, resume, proxies, and troubleshooting:

- [Account setup](DOCUMENTATION.md#account-setup)
- [Search API](DOCUMENTATION.md#search-api)
- [Profile tweets](DOCUMENTATION.md#profile-tweets)
- [Tweet lookup & replies](DOCUMENTATION.md#tweet-lookup--replies)
- [Followers / Following](DOCUMENTATION.md#followers--following)
- [User info](DOCUMENTATION.md#user-info)
- [Search users & trends](DOCUMENTATION.md#search-users)
- [Manifest refresh](DOCUMENTATION.md#manifest-refresh)
- [Saving results](DOCUMENTATION.md#saving-results)
- [Resume interrupted searches](DOCUMENTATION.md#resume-interrupted-searches)
- [Controlling limits](DOCUMENTATION.md#controlling-limits)
- [Configuration reference](DOCUMENTATION.md#configuration-reference)
- [Account management (ScweetDB)](DOCUMENTATION.md#account-management-scweetdb)
- [Async usage](DOCUMENTATION.md#async-usage)
- [Error handling](DOCUMENTATION.md#error-handling)
- [CLI reference](DOCUMENTATION.md#cli)

For advanced Twitter search operators, see [twitter-advanced-search](https://github.com/igorbrigadir/twitter-advanced-search).

---

<details>
<summary><strong>FAQ</strong></summary>

<br>

**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.5.0 release (2026-09-09) against X's current GraphQL API.

</details>

---

## Community

Have a question or want to share what you built with Scweet?
Open a thread in [**GitHub Discussions**](https://github.com/Altimis/Scweet/discussions).

**Found it useful? [Star the repo](https://github.com/Altimis/Scweet/stargazers)**

---

## Contributing

Bug reports, feature suggestions, and PRs are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).

---

*MIT License*
