<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0">

<channel>

<title>Блог об аналитике, визуализации данных, data science и BI, заметки с тегом: telethon</title>
<link>http://test.leftjoin.ru/tags/telethon/</link>
<description></description>
<generator>E2 (v3365; Aegea)</generator>

<item>
<title>Сбор информации о подписчиках Telegram-канала</title>
<guid isPermaLink="false">95</guid>
<link>http://test.leftjoin.ru/all/tg-api-parse/</link>
<comments>http://test.leftjoin.ru/all/tg-api-parse/</comments>
<description>
&lt;p&gt;На 2021 год боты в Telegram так и не имеют метода, позволяющего получать информацию о подписчиках канала. Тем не менее, существует достаточно сложное в освоении Telegram API и построенная на нём библиотека Telethon. Сегодня мы посмотрим, как при помощи библиотеки выгрузить информацию о подписчиках своего канала.&lt;/p&gt;
&lt;h2&gt;Создание приложения&lt;/h2&gt;
&lt;p&gt;Для начала необходимо создать приложение, через которое будут отправляться запросы к API. Перейдите на &lt;a href="https://my.telegram.org"&gt;https://my.telegram.org&lt;/a&gt; и авторизуйтесь в Telegram-аккаунте:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="http://test.leftjoin.ru/pictures/1-24.png" width="532" height="299" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;После успешной авторизации перейдите на страницу API development tools:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="http://test.leftjoin.ru/pictures/2-22.png" width="397" height="190" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Заполните все поля и жмите на создание приложения:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="http://test.leftjoin.ru/pictures/3-20.png" width="645" height="478" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Из полученной конфигурации нам необходим app api_id и app api_hash:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="http://test.leftjoin.ru/pictures/5-13.png" width="629" height="123" alt="" /&gt;
&lt;/div&gt;
&lt;h2&gt;Запрос к API&lt;/h2&gt;
&lt;p&gt;Импортируем telethon — он поможет сформировать запрос, и pandas — полученный ответ мы запишем в DataFrame.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;from telethon import TelegramClient
import pandas as pd&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Вводим api_id, api_hash, наш номер телефона и ссылку на канал, информацию о подписчиках которого хотим получить. Доступ к информации о подписчиках есть только у администраторов канала.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;api_id = 1234567
api_hash = '1b42hj25kd8jw42b234kwj242c'
phone = '+71234567890'
channel_href = 'https://t.me/leftjoin'&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Создаём новую сессию — вместо session_name можно подставить любое другое название. Методы в библиотеке работают асинхронно, поэтому ответа от них требуется ожидать:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;client = TelegramClient('session_name', api_id, api_hash)
client = await client.start()
dialogs = await client.get_dialogs()&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Собираем все каналы текущего пользователя. Из ссылки забираем часть с именем канала и вытаскиваем из словаря нужный:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;channels = {d.entity.username: d.entity
            for d in dialogs
            if d.is_channel}
my_channel = channel_href.split('/')[-1]
channel = channels[my_channel]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Подписчиков, доступ к которым не ограничен приватностью, можно получить методом get_participants. С 20 июля 2018 года Telegram установил ограничение в 200 подписчиков для вызова метода, и установка параметра aggressive на True поможет получить всех подписчиков за раз.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;members_telethon_list = await client.get_participants(channel, aggressive=True)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Из полученных библиотечных структур извлекаем информацию о пользователях — их имена и телефоны:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;username_list = [member.username for member in members_telethon_list]
first_name_list = [member.first_name for member in members_telethon_list]
last_name_list = [member.last_name for member in members_telethon_list]
phone_list = [member.phone for member in members_telethon_list]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Из четырёх списков собираем DataFrame и пишем его в csv-таблицу:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;df = pd.DataFrame()
df['username'] = username_list
df['first_name'] = first_name_list
df['last_name'] = last_name_list
df['phone'] = phone_list
df.to_csv('subscribers.csv', index=False)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Результат работы — такая таблица:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="http://test.leftjoin.ru/pictures/6-13.png" width="327" height="191" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Для запуска в Jupyter Notebook описанный ниже код можно просто вставить в ячейку, но при запуске из Python-файла будет такая ошибка:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;SyntaxError: 'await' outside function&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Устранить проблему можно, записав весь код в асинхронную функцию. Целиком выглядеть код будет так:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code&gt;from telethon import TelegramClient
import pandas as pd
import asyncio

async def main():
        api_id = 1234567
        api_hash = '1b42hj25kd8jw42b234kwj242c'
        phone = '+71234567890'
        channel_href = 'https://t.me/leftjoin'

	client = TelegramClient('session_name', api_id, api_hash)
	client = await client.start()
	dialogs = await client.get_dialogs()

	channels = {d.entity.username: d.entity
				for d in dialogs
				if d.is_channel}
	my_channel = channel_href.split('/')[-1]
	channel = channels[my_channel]

	members_telethon_list = await client.get_participants(channel, aggressive=True)

	username_list = [member.username for member in members_telethon_list]
	first_name_list = [member.first_name for member in members_telethon_list]
	last_name_list = [member.last_name for member in members_telethon_list]
	phone_list = [member.phone for member in members_telethon_list]

	df = pd.DataFrame()
	df['username'] = username_list
	df['first_name'] = first_name_list
	df['last_name'] = last_name_list
	df['phone'] = phone_list
	df.to_csv('subscribers.csv', index=False)

if __name__ == '__main__':
	loop = asyncio.get_event_loop()
	loop.run_until_complete(main())&lt;/code&gt;&lt;/pre&gt;</description>
<pubDate>Mon, 08 Feb 2021 15:19:17 +0300</pubDate>
</item>


</channel>
</rss>