<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Public Data Notes]]></title><description><![CDATA[Notes on getting public data into CSV with Python: Telegram channels, Google Ads Transparency and similar sources. Every post comes with working code (MIT, on G]]></description><link>https://publicdatanotes.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 01 Nov 2026 14:24:45 GMT</lastBuildDate><atom:link href="https://publicdatanotes.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to download a public Telegram channel's posts to CSV with Python (no API key, no phone number)]]></title><description><![CDATA[Download posts, views and reactions of public Telegram channels to CSV with Python. No API key or phone number. Real numbers from a 26 Oct 2026 run.]]></description><link>https://publicdatanotes.hashnode.dev/download-telegram-channel-posts-csv-python</link><guid isPermaLink="true">https://publicdatanotes.hashnode.dev/download-telegram-channel-posts-csv-python</guid><category><![CDATA[Python]]></category><category><![CDATA[web scraping]]></category><category><![CDATA[telegram]]></category><category><![CDATA[data]]></category><dc:creator><![CDATA[Çınar Özkan]]></dc:creator><pubDate>Mon, 26 Oct 2026 21:36:11 GMT</pubDate><content:encoded><![CDATA[<blockquote>
<p><strong>AI-assistance note:</strong> this article and the example code were written with the help of an AI assistant (Claude, by Anthropic). The code was run and the numbers below come from a real run on 26 Oct 2026. I also built the Actor used here, so I am not a neutral reviewer of it.</p>
</blockquote>
<p>Telegram's official API needs an account, a phone number and an app registration. For <em>public</em> channels there is an easier door: Telegram publishes a web preview of every public channel at <code>t.me/s/&lt;channel&gt;</code>. It shows the latest posts with text, date, views and reactions, 20 posts per page.</p>
<p>You can read that page yourself, but a real job needs more than one request: paging backwards, retries when Telegram answers 429, parsing the markup, turning <code>5.84M</code> into a number, telling a forwarded post from an original one. Here is the short route.</p>
<h2>What you need</h2>
<ul>
<li>A free Apify account. The free plan includes $5 of platform credit per month, and Apify's pricing page says paid Store Actors draw on the same credits.</li>
<li>The <a href="https://apify.com/kilometric_camp/telegram-channel-posts-scraper">Telegram Channel Posts Scraper</a> Actor. I built it. It costs $1 per 1,000 results (a post or a channel summary row each count as one), with no start fee. By my arithmetic the free credit covers about 5,000 posts a month.</li>
<li>Python 3.11+ (required by the current <code>apify-client</code>) and two small scripts from <a href="https://github.com/thecbstudio/telegram-channel-posts-examples">this repo</a> (MIT).</li>
</ul>
<h2>Download the posts</h2>
<pre><code class="language-bash">pip install -r requirements.txt
export APIFY_TOKEN=...        # Apify Console -&gt; Settings -&gt; API &amp; integrations
python fetch_posts.py durov telegram --max 60
</code></pre>
<p>You get <code>posts.csv</code> with channel, post link, date (UTC), views, reactions, media types, hashtags and text. Filters help for real work: <code>--since "30 days"</code> and <code>--keywords price launch</code> keep only recent posts that mention your words.</p>
<h2>What the data showed</h2>
<p>I ran it on two official channels, 60 posts each (26 Oct 2026):</p>
<table>
<thead>
<tr>
<th>Channel</th>
<th>Subscribers</th>
<th>Posts covered</th>
<th>Median views</th>
<th>Best post</th>
</tr>
</thead>
<tbody><tr>
<td>durov</td>
<td>10.2M</td>
<td>13 Apr – 11 Oct 2026</td>
<td>4.74M</td>
<td>24.4M (15 Jun)</td>
</tr>
<tr>
<td>telegram</td>
<td>9.24M</td>
<td>18 Aug 2025 – 26 Aug 2026</td>
<td>2.06M</td>
<td>3.88M (2 Sep 2025)</td>
</tr>
</tbody></table>
<p>A few things a report like this makes easy to see:</p>
<ul>
<li><strong>When they post.</strong> Most posts of the durov channel went out at 15:00 UTC (10 of 60), then 14:00 and 17:00 (7 each). The <code>telegram</code> channel clusters at 16:00–17:00 UTC (30 of 60).</li>
<li><strong>What got the most views.</strong> The three biggest durov posts were a contest announcement, a formatting update and a policy post, with 24.4M, 23.2M and 19.0M views.</li>
<li><strong>Media vs text.</strong> Text-only durov posts averaged 7.35M views, photo posts 4.81M. That is 33 versus 9 posts, so treat it as a hint, not a rule.</li>
</ul>
<pre><code class="language-bash">python channel_report.py posts.csv
</code></pre>
<p>prints this kind of summary for any CSV you make.</p>
<h2>Limits to know about</h2>
<ul>
<li>Only channels whose public web preview is switched on can be read. Private channels, groups, users and bots cannot.</li>
<li>Telegram rounds big numbers on that page, so views and subscribers above a few thousand are approximate.</li>
<li>Media links are temporary, so download files soon after the run.</li>
<li>There is no search across all of Telegram. You give the channels, the keyword filter works inside each one.</li>
<li>Be careful with personal data. Follow Telegram's terms and the privacy laws that apply to you.</li>
</ul>
<h2>Try it, tell me what breaks</h2>
<p>If a channel returns nothing or a field looks wrong, open an issue on the repo or on the Actor page with the channel name and what you expected. I read them.</p>
<p><em>Not affiliated with Telegram.</em></p>
]]></content:encoded></item></channel></rss>