Scweet Documentation

repository·master·Indexed 23 days ago

https://github.com/altimis/scweet

Scweet is a tool for scraping tweets, profile timelines, followers, and user profiles from Twitter/X without using the official API. It can be run locally via Python/CLI or as a hosted service on Apify. The library supports authentication via browser cookies (auth_token), proxy integration to reduce ban risk, and account provisioning using a local SQLite database. Key features include advanced search filters, async method variants, and the ability to export results to CSV and JSON.

Tokens
10K
Snippets
28
Records
49
Agent score
80%

What's inside Scweet

  1. Scweet exception hierarchy

    master

    Scweet uses a structured exception hierarchy. You can catch specific errors or use ScweetError as a catch-all.

    • ScweetError (Base)
      • AccountPoolExhausted: No eligible accounts (all cooled down or at daily limits).
      • EngineError: Engine-level runtime error.
        • RunFailed: Run completed but couldn't produce results.
          • RateLimitError: All accounts rate-limited (429).
          • AuthError: Credentials invalid or expired (401/403).
          • NetworkError: Network/connectivity failure.
          • ProxyError: Proxy misconfiguration or connectivity failure.
  2. How Scweet account provisioning works

    master

    When you initialize a Scweet instance, it provisions your accounts into a local SQLite database (default: scweet_state.db).

    Key behaviors:

    • Automatic Storage: Cookies are imported, validated, and stored to manage rate limits, cooldowns, and daily caps.
    • Persistence: You only need to provide credentials once. Subsequent runs can reuse the database.
    • Deduplication: If an account already exists in the DB (matched by username or auth_token), it is updated rather than duplicated.
    • Control: Provisioning is enabled by default (provision=True).

    Reusing an existing database: To use accounts already in your DB without re-providing cookies:

    s = Scweet(db_path="scweet_state.db")

    To skip provisioning and only work with existing accounts:

    s = Scweet(db_path="scweet_state.db", provision=False)
  3. Control scraping limits with the limit parameter

    master

    Scweet provides two layers of limits to protect your accounts:

    1. Per-call limit: A parameter passed to pagination methods (search, get_profile_tweets, get_followers, get_following). It defines the maximum number of items to collect in that specific call. It is highly recommended to always set this to avoid burning through account quotas.
    2. Account daily caps: Configured via ScweetConfig (daily_requests_limit, daily_tweets_limit). These act as safety nets for the total number of requests/tweets allowed per account per UTC day.

    Example usage of per-call limit:

    tweets = s.search("python", limit=200)              # stop after 200 tweets
    tweets = s.get_profile_tweets(["elonmusk"], limit=100)
    users  = s.get_followers(["elonmusk"], limit=500)
    tweets = s.search("python", limit=200)
  4. Configure Scweet logging

    master

    Scweet uses the standard Python logging module under the "Scweet" namespace. By default, no output is produced. To see logs, configure a handler for the "Scweet" logger.

    import logging
    
    logging.basicConfig(level=logging.INFO)
    # or target only Scweet:
    logging.getLogger("Scweet").setLevel(logging.INFO)
    logging.getLogger("Scweet").addHandler(logging.StreamHandler())
  5. Enable auto-updating GraphQL query IDs

    master

    Twitter/X rotates GraphQL query IDs periodically. To ensure your requests use current IDs, you can enable manifest_scrape_on_init=True in the Scweet constructor. This fetches the current main.js bundle from X on initialization and extracts the latest IDs. This adds a few seconds to startup time.

    # Python
    s = Scweet(cookies_file="cookies.json", manifest_scrape_on_init=True)
    # CLI
    scweet --auth-token TOKEN --manifest-scrape-on-init search "query" --limit 100
  6. Use Scweet in Python

    master

    Initialize the Scweet class with your auth_token. You can also provide a proxy for increased security and reduced ban risk.

    Note: Always set a limit to prevent scraping until your account's daily cap is hit. All methods have async variants (e.g., asearch(), aget_profile_tweets()).

    from Scweet import Scweet
    
    # Credentials are stored in scweet_state.db automatically on first run
    s = Scweet(auth_token="YOUR_AUTH_TOKEN", proxy="http://user:pass@host:port")
    
    # Search tweets — save to CSV (save_format="json" or "both" also works)
    tweets = s.search("bitcoin", since="2025-01-01", limit=500, save=True)
    
    # Reuse provisioned accounts on subsequent runs using the state database
    s = Scweet(db_path="scweet_state.db")
    tweets = s.search("ethereum", limit=500, save=True)
  7. Configure Scweet using inline cookies

    master

    For one-off runs or simple scripts, you can pass cookies directly into the Scweet constructor.

    Single account:

    s = Scweet(cookies={"auth_token": "...", "ct0": "..."})

    Multiple accounts:

    s = Scweet(cookies=[
        {"auth_token": "tok1", "ct0": "ct0_1"},
        {"auth_token": "tok2", "ct0": "ct0_2"},
    ])
  8. Configure Scweet accounts using cookies.json

    master

    The recommended way to provide Twitter/X authentication is via a cookies.json file. You can obtain your auth_token and ct0 values from your browser's DevTools (Application > Cookies > https://x.com).

    Scweet can handle multiple accounts, each with its own optional proxy to reduce ban risk and enable concurrent scraping.

    Example cookies.json structure:

    [
      {
        "username": "your_account",
        "cookies": { "auth_token": "..." }
      }
    ]

    Usage:

    s = Scweet(cookies_file="cookies.json")
  9. Migrate from Scweet v4 to v5

    master

    If you are upgrading from version 4, note the following API changes:

    v4v5
    Scweet.from_sources(...)Scweet(cookies_file=...)
    scweet.scrape(words=["bitcoin"], ...)s.search("bitcoin", ...)
    scweet.ascrape(...)s.asearch(...)
    scweet.profile_tweets(usernames=[...])s.get_profile_tweets([...])
    scweet.get_user_information(usernames=[...])s.get_user_info([...])
    ScweetConfig.from_sources(overrides={...})ScweetConfig(field=value)
    Nested config (pool.concurrency)Flat config (concurrency)
    from Scweet.scweet import Scweetfrom Scweet import Scweet
  10. Resume interrupted searches

    master

    You can resume a search from a previous checkpoint using the resume=True parameter. This works by matching a hash of the query parameters. To resume correctly, you must provide the exact same since, until, query, lang, and display_type used in the original run.

    # First run — gets interrupted or completes partially
    tweets = s.search("query", since="2024-01-01", until="2024-06-01", limit=1000)
    
    # Resume — picks up from last saved checkpoint
    tweets = s.search("query", since="2024-01-01", until="2024-06-01", limit=1000, resume=True)
  11. Configure Scweet using auth_token (Quickest)

    master

    If you only have an auth_token, Scweet will automatically bootstrap the ct0 value for you. You can also provide a global proxy directly during initialization.

    Single account:

    s = Scweet(auth_token="YOUR_AUTH_TOKEN")

    With global proxy:

    s = Scweet(auth_token="YOUR_AUTH_TOKEN", proxy="http://user:pass@host:port")