# How to Collect Tweets With Python

To collect tweets with Python, install the apify-client package, run apidojo's Tweet Scraper V2 with an X search query, and iterate over the run's dataset.

[![apidojo](/blog/authors/apidojo.png)**Apidojo** *15+ years of experience in data retrieval.*](/blog/authors/apidojo/)

**7 October 2026** Published

**4 min** Read

![Cover card reading 'How to Collect Tweets With Python (2026)'](/blog/covers/scrape-tweets-python.png)

**To collect tweets with Python, install the `apify-client` package, run apidojo’s Tweet Scraper V2 with an X search query, and iterate over the run’s dataset.** Ten lines of code return posts with text, date, author and engagement at $0.40 per 1,000 tweets, with no X developer account.

This guide builds a complete Python collector: setup, a first run, parsing dates, date-window batching, deduplication and saving to CSV. The actor choice is explained in [how to scrape Twitter data in 2026](/blog/twitter-scraping/how-to-scrape-twitter/).

## What Do You Need to Collect Tweets With Python?

**You need Python 3, the `apify-client` package, and an Apify API token from a paid Apify plan.** Tweet Scraper V2 can’t be called through the API on the free plan ([Apify](https://apify.com/apidojo/tweet-scraper)). Listed below are the 3 setup steps.

1.  **Install** the client: `pip install apify-client pandas`.
2.  **Copy** your API token from Apify Console.
3.  **Store** it in an environment variable: `export APIFY_TOKEN=your_token`.

## How Do You Run a First Tweet Collection in Python?

**You run a first collection by calling the actor with a `searchTerms` query and reading items from its default dataset.** The field names below come from the actor’s output example (Apify).

```
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("apidojo/tweet-scraper").call(run_input={
    "searchTerms": ["from:NASA -filter:retweets"],
    "sort": "Latest",
    "maxItems": 500,
})

for tweet in client.dataset(run.default_dataset_id).iterate_items():
    print(tweet["createdAt"], tweet["likeCount"], tweet["text"][:80])
```

`call()` starts the run and waits for it to finish. Every X search operator works in the query; see the [Twitter advanced search operators](/blog/twitter-search/advanced-search-operators/) reference.

## How Do You Parse Tweet Dates in Python?

**Tweet Scraper V2 returns `createdAt` in the format `Fri Nov 24 17:49:36 +0000 2023`, which `datetime.strptime` parses with `%a %b %d %H:%M:%S %z %Y`.**

```
from datetime import datetime

def parse_created_at(value: str) -> datetime:
    return datetime.strptime(value, "%a %b %d %H:%M:%S %z %Y")

print(parse_created_at("Fri Nov 24 17:49:36 +0000 2023"))
```

## How Do You Collect a Large History in Python?

**Collect a large history by generating one query per date window and running them in batches of 5, the maximum per Tweet Scraper V2 run.** Store posts in a dictionary keyed by `id` to remove duplicates (Apify).

```
from datetime import date

def month_windows(start: date, end: date):
    current = start
    while current < end:
        nxt = date(current.year + current.month // 12, current.month % 12 + 1, 1)
        yield current, min(nxt, end)
        current = nxt

queries = [f"from:NASA since:{a} until:{b}" for a, b in month_windows(date(2025, 1, 1), date(2026, 1, 1))]
tweets = {}

for i in range(0, len(queries), 5):
    run = client.actor("apidojo/tweet-scraper").call(run_input={
        "searchTerms": queries[i:i + 5],
        "includeSearchTerms": True,
        "sort": "Latest",
    })
    for item in client.dataset(run.default_dataset_id).iterate_items():
        tweets[item["id"]] = item

print(len(tweets), "unique tweets")
```

Window sizes are discussed in [how to scrape tweets by date range](/blog/twitter-scraping/scrape-tweets-by-date/), and deduplication in [Twitter scraper pagination](/blog/twitter-scraping/pagination/).

## How Do You Save Tweets to CSV With pandas?

**Flatten the posts with `pandas.json_normalize`, keep the columns you need, and write a CSV.** Nested author fields become columns such as `author.userName`.

```
import pandas as pd

df = pd.json_normalize(list(tweets.values()))
columns = ["id", "url", "createdAt", "author.userName", "text",
           "likeCount", "retweetCount", "replyCount", "quoteCount"]
df[columns].to_csv("tweets.csv", index=False)
```

Keep `id` as text in spreadsheets so the 19-digit IDs aren’t rounded. Other formats are covered in [how to export tweets to CSV or JSON](/blog/twitter-scraping/export-tweets-csv-json/).

## Which Other apidojo Actors Work From Python?

**Every apidojo actor runs from Python the same way; only the actor ID and input change.** Listed below are the 4 you are most likely to need.

| Task | Actor ID | Key input |
| --- | --- | --- |
| Small queries, single posts, threads | apidojo/twitter-scraper-lite | searchTerms, startUrls, conversationIds |
| Replies to posts | apidojo/twitter-replies-scraper | Post IDs or URLs |
| Profiles, followers, following | apidojo/twitter-user-scraper | twitterHandles, getFollowers, getFollowing |
| Profile timelines with replies | apidojo/twitter-profile-scraper | Profiles |

Threads in Python are shown in [how to scrape a Twitter thread and all its replies](/blog/twitter-scraping/scrape-thread-replies/). The official X API in Python, with `requests` and a bearer token, is covered in [how to get historical tweets with an API](/blog/twitter-api/historical-tweets/).

## The scrapers behind this

-   [Tweet Scraper V2 Tweets from searches, profiles, Lists and URLs; 49–64 tweets/sec; minimum 50 per query $0.40 / 1K tweets](/scrapers/twitter-scraper/)

## Questions people ask

### Do you need Tweepy?

No, Tweepy wraps the official X API; the Apify client runs apidojo's actors without an X developer account.

### Can you run the collector on a schedule?

Yes, with Apify schedules or cron, but use Twitter Scraper Unlimited for recurring queries; see [how to monitor a keyword on X with an API](/blog/twitter-scraping/monitor-keyword/).

### Is there a JavaScript version?

Yes, see [how to collect tweets with JavaScript and Node.js](/blog/twitter-scraping/scrape-tweets-javascript/).

### Where do you start?

At the [apidojo Twitter Scraper](/scrapers/twitter-scraper/).

## More on scraping X data

-   [How to Scrape Twitter (X) Data in 2026 What Twitter data you can scrape, the 3 ways to collect it, which apidojo actor fits each task, prices, limits and Python code.](/blog/twitter-scraping/how-to-scrape-twitter/)
-   [How to Scrape Tweets by Keyword (2026 Guide) Scrape tweets by keyword with apidojo's Tweet Scraper V2: query rules, batching, Python code, costs and fixes for low results.](/blog/twitter-scraping/scrape-tweets-by-keyword/)
-   [How to Scrape Tweets by Date Range Scrape tweets between two dates by splitting periods into windows, running them in batches and removing duplicates, with Python code.](/blog/twitter-scraping/scrape-tweets-by-date/)
-   [How to Scrape Tweets From a User Profile Scrape any public profile's tweets with from:username, collect a full history in date windows, and compare two apidojo actors.](/blog/twitter-scraping/scrape-user-tweets/)
-   [How to Scrape Twitter Search Results Turn any X search into a JSON, CSV or Excel dataset with apidojo's Tweet Scraper V2, using search queries or search result URLs.](/blog/twitter-scraping/scrape-search-results/)
-   [How to Scrape a Twitter Thread and All Replies Scrape every reply in a thread with conversation\_id:, keep only the author's thread, filter replies and see what each thread costs.](/blog/twitter-scraping/scrape-thread-replies/)
-   [How to Scrape Images and Videos From Tweets Collect tweets with media, find the media URLs in the output, download images with Python and pick the best video file.](/blog/twitter-scraping/scrape-twitter-media/)
-   [How to Export Tweets to CSV or JSON Export tweets to CSV, Excel, JSON or JSONL: your own archive, any search through a scraper, the columns you get and the API call.](/blog/twitter-scraping/export-tweets-csv-json/)
-   [How to Collect Tweets With JavaScript and Node.js A complete Node.js tweet collector: setup, first run, safe tweet IDs, date-window batching, deduplication and CSV export.](/blog/twitter-scraping/scrape-tweets-javascript/)
-   [Twitter Scraper Pagination: Cursors and Limits How pagination works in the X API and apidojo's actors, why searches stop early, and how to deduplicate and resume collections.](/blog/twitter-scraping/pagination/)
-   [How to rebuild an X conversation tree from replies Replies arrive as a flat list. Two fields, conversationId and inReplyToId, are what turn that list back into the threaded conversation you saw on X.](/blog/twitter-scraping/x-reply-tree/)
-   [When the X replies endpoint under-returns A thread that looks busy on X can come back thin from a scrape. Here is how to tell a quiet conversation from a short run, and what the second flow fixes.](/blog/twitter-scraping/x-replies-vs-search-flow/)
-   [Reading account age in X reply data Every reply carries the responder's account creation date, follower counts and post history. Here is what those fields can and cannot tell you.](/blog/twitter-scraping/x-replier-account-age/)

![apidojo](/blog/authors/apidojo.png)

## [Apidojo](/blog/authors/apidojo/)

15+ years of experience in data retrieval.

API Dojo is always ready for you. With 15+ years of experience, data acquisition has never been that easy. Cheapest prices with high availability.

-   🏯 15+ years of experience in data retrieval.
-   💰 Cheapest prices, qualified data.
-   ⚙️ High availability, extreme maintenance.
-   🐉 Hyper communicative, excellent support.

-   [apify.com](https://apify.com/apidojo)
-   [x.com](https://x.com/apidojo_)
-   [github.com](https://github.com/apidojo-io)
