twscrape Documentation

repository·main·Indexed 25 days ago

https://github.com/vladkens/twscrape

A Python-based tool and API for scraping data from X (formerly Twitter) using GraphQL and Search API implementations with SNScrape data models. It provides a CLI and an async Python API for automation, featuring account session management via cookies, account rotation through AccountsPool to avoid rate limits, and support for proxy configuration and custom HTTP backends like curl-cffi.

Tokens
8.7K
Snippets
9
Records
61
Agent score
82%

What's inside twscrape

  1. Configure Proxy priority and usage

    main

    Proxies can be applied at different levels. The priority order is:

    1. api.proxy (highest)
    2. TWS_PROXY environment variable
    3. Account-specific proxy (lowest)

    Python API usage:

    Set a proxy for the entire API instance:

    api = API(proxy="http://login:pass@example.com:8080")

    Set a proxy for a specific account:

    await api.pool.add_account(
        "user1",
        "pass1",
        "user1@example.com",
        "email_pass1",
        proxy="http://login:pass@example.com:8080",
    )

    CLI usage:

    TWS_PROXY=socks5://user:pass@127.0.0.1:1080 twscrape user_by_login xdevelopers
    await api.pool.add_account(
        "user1",
        "pass1",
        "user1@example.com",
        "email_pass1",
        proxy="http://login:pass@example.com:8080",
    )
    
    api = API(proxy="http://login:pass@example.com:8080")
    doc = await api.user_by_login("xdevelopers")
  2. Set up accounts using browser cookies

    main

    The most stable way to add accounts is using browser cookies containing auth_token and ct0. Cookie accounts with ct0 are activated immediately and do not require a login_accounts step.

    To get cookies:

    1. Open x.com in a browser.
    2. Open DevTools (F12).
    3. Go to Application -> Cookies.
    4. Copy the auth_token and ct0 values.

    CLI Usage:

    Add a cookie-based account:

    twscrape add_cookie my_account "auth_token=xxx; ct0=yyy"

    Or prompt for the cookie value interactively:

    twscrape add_cookie my_account
  3. Handle async generator cleanup with aclosing

    main

    When breaking out of an async generator (like api.search) early, use contextlib.aclosing to ensure the account lock is released promptly.

    from contextlib import aclosing
    
    async with aclosing(api.search("elon musk")) as gen:
        async for tweet in gen:
            if tweet.id < 200:
                break
  4. Use the twscrape Python API

    main

    The Python API provides an async interface for scraping X/Twitter. You can initialize the API class with an optional database path. Use gather() to collect results from async generators into a list, or iterate over the async generators directly for streaming.

    import asyncio
    from twscrape import API, gather
    
    async def main():
        api = API()  # or API("accounts.db")
    
        # Add account cookies (stored in the database)
        await api.pool.add_account_cookies("my_account", "auth_token=xxx; ct0=yyy")
    
        # Fetch a user
        user = await api.user_by_login("xdevelopers")
        print(user.id, user.username, user.followersCount)
    
        # Search and gather results
        tweets = await gather(api.search("from:xdevelopers lang:en", limit=20))
        for tweet in tweets:
            print(tweet.id, tweet.user.username, tweet.rawContent)
    
        # Streaming results
        async for tweet in api.search("open source lang:en", limit=100):
            print(tweet.id, tweet.rawContent)
    
    if __name__ == "__main__":
        asyncio.run(main())
    import asyncio
    from twscrape import API, gather
    
    async def main():
        api = API()  # or API("accounts.db")
    
        # Add once; the session is stored in the account database.
        await api.pool.add_account_cookies("my_account", "auth_token=xxx; ct0=yyy")
    
        user = await api.user_by_login("xdevelopers")
        print(user.id, user.username, user.followersCount)
    
        tweets = await gather(api.search("from:xdevelopers lang:en", limit=20))
        for tweet in tweets:
            print(tweet.id, tweet.user.username, tweet.rawContent)
    
    
    if __name__ == "__main__":
        asyncio.run(main())
  5. Install twscrape

    main

    Install the core library using pip:

    pip install twscrape

    For browser-like TLS fingerprinting, install the optional curl-cffi backend. You can then use the curl backend by setting the TWS_HTTP_BACKEND environment variable:

    pip install "twscrape[curl]"
    
    TWS_HTTP_BACKEND=curl twscrape user_by_login xdevelopers
  6. Handle QueueClient exceptions

    main

    When using QueueClient, certain exceptions are raised to the caller that indicate the request cannot proceed:

    • GqlFeaturesOutdatedError: Raised when the internal GQL features no longer match the X API. This indicates the twscrape library needs an update and retrying will not help.
    • AbortReqError: Raised when a request is aborted (e.g., due to Cloudflare blocking or internal dependency errors).
    • ConnectError: Raised if the proxy is misconfigured or the host is unreachable after 3 attempts.

    Other errors like HandledError (rate limits) or XClIdAccountError are caught internally by QueueClient to trigger account rotation or locking.

  7. How account locking and queues work

    main

    The AccountsPool uses a locking mechanism to manage concurrency. When an account is retrieved via get_for_queue, a lock is placed on that account for the specified queue name in the database. This lock is stored as a JSON object in the locks column.

    Key behaviors:

    • Automatic Expiry: Locks are typically set to expire after 15 minutes. An account is considered available for a queue if its lock for that queue is NULL or if the lock timestamp is in the past.
    • Concurrency Control: By using different queue names (e.g., "search" vs "profile_scraping"), you can allow an account to be used for one task type while it is locked for another.
    • Wait Logic: get_for_queue_or_wait uses next_available_at to determine when the next account in the queue will become free, allowing it to sleep efficiently between polls rather than busy-waiting.
  8. Search and retrieve data via twscrape CLI

    main

    The CLI provides several commands to search for tweets and retrieve user/community data. Most search commands support a --limit flag to restrict the number of results and a --raw flag to print the raw JSON response instead of the parsed model.

    Search Commands

    CommandArgumentDescriptionLimit Support
    searchquerySearch for tweetsYes
    tweet_detailstweet_id (int)Get tweet detailsNo
    tweet_repliestweet_id (int)Get replies of a tweetYes
    tweet_threadtweet_id (int)Get thread tweetsYes
    retweeterstweet_id (int)Get retweeters of a tweetYes
    user_by_loginusernameGet user data by usernameNo
    user_aboutusernameGet about info for usernameNo
    followinguser_id (int)Get user followingYes
    followersuser_id (int)Get user followersYes
    verified_followersuser_id (int)Get user verified followersYes
    subscriptionsuser_id (int)Get user subscriptionsYes
    user_tweetsuser_id (int)Get user tweetsYes
    user_tweets_and_repliesuser_id (int)Get user tweets and repliesYes
    user_mediauser_id (int)Get user's mediaYes
    list_timelinelist_id (int)Get tweets from listYes
    list_memberslist_id (int)Get List members by list IDYes
    community_infocommunity_id (str)Get community infoNo
    community_memberscommunity_id (str)Get community membersYes
    community_moderatorscommunity_id (str)Get community moderatorsYes
    community_tweetscommunity_id (str)Get community tweetsYes
    trendstrend_id (str)Get trends (ID or name)Yes

    Example Usage

    # Search for tweets with a limit
    twscrape search "python programming" --limit 10
    
    # Get raw JSON for a tweet
    twscrape tweet_details 123456789 --raw
    
    # Get followers of a user
    twscrape followers 987654321 --limit 50
  9. Manage accounts via twscrape CLI

    main

    Use the twscrape CLI to manage your account pool, including adding, deleting, and logging in accounts. All account operations are stored in a SQLite database (default: accounts.db).

    Account Management Commands

    • Add accounts from a file: add_accounts <file_path> [--line-format <format>]
      • After adding, you must run login_accounts to activate them.
    • Add account via cookies: add_cookie <username> [cookies]
      • If cookies is omitted, you will be prompted to enter them (e.g., auth_token=xxx; ct0=yyy).
    • Delete accounts: del_accounts <usernames...>
    • List all accounts: accounts
    • Get usage statistics: stats (shows total, active, inactive, and locked accounts)
    • Login accounts: login_accounts [--email-first] [--manual]
      • --email-first: Check email for codes first.
      • --manual: Enter email codes manually.
    • Retry logins:
      • relogin_failed: Retry all failed account logins.
      • relogin <usernames...>: Re-login specific accounts.
    • Maintenance:
      • reset_locks: Reset all account locks.
      • delete_inactive: Remove inactive accounts from the database.
  10. Configure API behavior (timeouts and errors)

    main

    When initializing the API class, you can control how it handles account availability:

    • raise_when_no_account=True: Raises NoAccountError instead of waiting indefinitely.
    • wait_timeout: Limits how long to wait for a locked account (in seconds).
    • wait_interval: Controls how often the pool checks for available accounts (in seconds).
    api = API(raise_when_no_account=True, wait_timeout=30, wait_interval=1)
  11. Configure login behavior with LoginConfig

    main

    The LoginConfig dataclass allows you to customize the authentication flow for an account:

    • email_first (bool): If set to True, the system attempts to handle email-based authentication steps earlier in the process. Defaults to False.
    • manual (bool): If set to True, the system will prompt for manual user input (e.g., via input()) when an email confirmation code is required, rather than attempting to fetch it automatically via IMAP. Defaults to False.
  12. Configure the HTTP backend via environment variables

    main

    You can control which HTTP client twscrape uses by setting the TWS_HTTP_BACKEND environment variable.

    • TWS_HTTP_BACKEND=curl: Forces the use of CurlClient (requires curl-cffi).
    • TWS_HTTP_BACKEND=httpx: Forces the use of HttpxClient (requires httpx).

    If curl is selected but curl-cffi is not installed, an ImportError will be raised with instructions to install it.