Every guide to scraping Telegram starts the same way: register an application at my.telegram.org, get an api_id and api_hash, log in with your phone number, manage a session string with Telethon or Pyrogram, and hope your account doesn't get limited.
For public channels, none of that is necessary. Telegram publishes a full web preview of every public channel that anyone — including a plain HTTP client — can read. Here's how it works, and where its limits are.
The t.me/s/ trick
Every public channel has a server-rendered preview at:
https://t.me/s/{channel_name}
Open https://t.me/s/telegram in a browser with JavaScript disabled — the messages are still there. It's plain HTML, served to any User-Agent, with no login, no cookies, no API key, and no bot token.
Even better: it paginates. Each page shows ~20 messages, and appending ?before={message_id} walks backward through history:
import re, requests
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."
s = requests.Session(); s.headers["User-Agent"] = UA
html = s.get("https://t.me/s/durov").text
ids = [int(x) for x in re.findall(r'data-post="[^/]+/(\d+)"', html)]
older = s.get(f"https://t.me/s/durov?before={min(ids)}").text # next 20, older
What's actually in the preview
More than most people assume. Each tgme_widget_message block contains:
- Full message text (with formatting markup you can strip or keep)
-
Timestamp — a proper ISO 8601
datetimeattribute - View count ("1.1M" style, abbreviated)
- Reactions — per-emoji counts, including paid Star reactions. This surprises people; most scrapers never parse the reactions footer at all
-
Media — direct CDN URLs for photos and video files (
cdn*.telesco.pe), plus thumbnails - Links and link previews, forwarded-from attribution, reply context, post author
- Channel-level: title, description, subscriber count, avatar
What's not there: discussion-group comments, poll internals, subscriber-only content, and anything from private channels or groups — those genuinely require the real API and an account. Individual user accounts and bots have no preview either.
The gotchas (why "just regex it" grows teeth)
- Non-channels return HTTP 200 with an empty preview, not a 404 — so "no messages" and "not a public channel" look identical unless you also check for channel metadata.
- The message text div ends at the first
</div>— greedy patterns swallow the footer, reactions, and "VIEW IN TELEGRAM" boilerplate into your text. - Counts come abbreviated (
10.2K,1.1M) and need normalizing; custom emoji reactions are<tg-emoji>elements with IDs, not characters. - Albums, voice notes, stickers, and documents each have their own markup variants.
- At volume you'll want polite pacing and IP rotation — Telegram is tolerant, but not infinitely.
The maintained shortcut
I packaged all of the above as an Apify Actor: Telegram Channel Scraper. Give it channel names in any form (durov, @durov, t.me/durov), get structured JSON/CSV:
{
"channel": "durov",
"message_id": 527,
"datetime": "2026-06-15T12:04:11+00:00",
"text": "🏆 Telegram is launching a $200,000 contest for content creators.",
"views": 21900000,
"total_reactions": 514000,
"reactions": [{ "emoji": "⭐paid", "count": 24900 }],
"media_type": "video",
"videos": ["https://cdn4.telesco.pe/file/...mp4"],
"url": "https://t.me/durov/527"
}
It handles the pagination, the empty-preview trap, reaction parsing, media extraction, and keyword filtering — priced per message (about a tenth of a cent), runs on a schedule for monitoring, and plugs into Sheets/webhooks/LLM pipelines via the Apify API and MCP. A 50-message pull across two channels takes about six seconds.
Typical uses: monitoring crypto/announcement channels, OSINT with timestamps and reach metrics, competitor watching, and turning channels into clean text datasets for RAG.
FAQ
Is this against Telegram's rules? It reads content Telegram itself publishes to any anonymous web visitor. No authentication is bypassed and no private data is touched.
Can I get comments or poll results? No — those aren't in the public preview. That's real-API territory (Telethon/Pyrogram with an account).
How far back can I scrape? The ?before= pagination walks to the channel's first message if you let it.
Why not just use the Bot API? Bots must be added to a channel by an admin. The preview needs nothing.
If you hit a channel that parses oddly, open an issue on the actor — real examples are how coverage improves.
Top comments (0)