DeSoft.ru
236 subscribers
116 photos
10 videos
1 file
213 links
Авторский канал: ИТ, разработка, безопасность, администрирование.

Сайт: desoft.ru
Автор: @y_demin
Download Telegram
Для автоматизации задач сбора информации из каналов, групп, чатов в Telegram, помимо официального API, существуют различного рода и направленности, как платные так и бесплатные, инструменты и библиотеки. В данном цикле заметок рассмотрим примеры работы с популярной Python библиотекой Telethon в контексте извлечения полезных данных из публичных просторов мессенджера.

Для удобства исходники выложены в репозиторий на gitverse.

📌 Задача

Выгрузить все изображения (документы, аудиофайловы) из открытого Telegram-канала в автоматическом режиме.

📌 Рабочая станция

Виртуальная машина с Debian 12 на борту.

📌 Подготовка

🔹 Для начала получим параметры для доступа к API Telegram

* Идем в кабинет и авторизовываемся.

* На странице API development tools создаем новое приложение и забираем App api_id и App api_hash.

🔹 Устанавливаем необходимые для работы пакеты
sudo apt install git python3 python3-pip python3-vevn -y


🔹 Скачиваем демонстрационный проект с gitverse
git clone https://gitverse.ru/desoft/telethoner.git


🔹 Создаем виртуальное окружение и подгружаем зависимости
cd telethoner
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt


🔹 В скрипте downloader.py прописываем полученные ранее App api_id и App api_hash в константы API_ID и API_HASH соответственно.

📌 Использование

🔹 При первом запуске для получения доступа к API Telegram необходимо будет войти под своей учетной записью в интерактивном режиме (вводим номер телефона, получаем и заполняем код).
Please enter your phone (or bot token): +7...............
Please enter the code you received: 00000
Signed in successfully as <USER>;


В корне создастся файл с расширением .session, который будет использоваться для автоматической аутентификации при последующих запусках.

🔹 В качестве примера добавлена обработка трех видов контента - документы, фото и музыка, что соответствует значениям document, photo, music параметра content_type.

🔹 Запускаем
# скачиваем 10 прикрепленных изображений к последним постам в Telegram-канале Хабра
python3 downloader.py --channel_url=https://t.me/habr_com --content_type=photo --path_data_folder=myfolder --limit=10


#telegram #python #telethon
👍2
Дополняю созданный ранее репозиторий со скриптами для сбора информации из Telegram еще несколькими примерами.

✏️ На этот раз пробуем выгружать и сохранять списки участников публичных каналов, групп, чатов, где состоит пользователь, учетные данные которого используются для работы с Telegram API.

Приведу здесь фрагменты исходного кода. Полная версия демонстрационного скрипта в репозитории.
# получаем список каналов, групп, чатов пользователя
result = await client(GetDialogsRequest(
offset_date=None,
offset_id=0,
offset_peer=InputPeerEmpty(),
limit=100,
hash = 0
))
print(result.chats)


# выгружаем список участников конкретного чата
users = await client.get_participants(chat)
print(users)


❗️ Если у пользователя недостаточно прав на получение информации об участниках какого-либо канала или группы, то будет выброшен Exception с соответствующей информацией.

✏️ В предыдущей заметке рассматривал примеры поиска сообщений с определенным содержимым (фото, документы, аудио). В данном варианте представлен сбор информации не только о публичном канале и сообщениях в нем, но и о комментариях к каждому посту.

Также привожу фрагменты исходного кода. Полная версия в репозитории.
 # информация о канале по его адресу или id
channel = await client.get_entity(url)
print(channel)


 # выгрузка последних 10 постов канала
async for message in client.iter_messages(channel, limit=10):
# выгрузка всех комментариев к конкретному посту
async for comment in client.iter_messages(channel, reply_to=message.id):
print(comment.text)


#telegram #python #telethon
🔥3👍1
Задача о выгрузке информации о странах получила свое продолжение. Для собранных данных о геолокации стран (координаты столицы, крупных городов) необходимо сделать соответствующие отметки на карте.

📝 Имеем географические координаты (широту и долготу) и карту в виде изображения, на которое и нужно нанести метки, т.е.преобразовать точку трехмерного пространства в двумерное, построить проекцию.

📚 С решением задачи нам поможет картографическая проекция Меркатора, а точнее ее вариант WGS 84 / Pseudo-Mercator, который используется в современных картографических приложениях и сервисах.
WGS - всемирная геодезическая система, в настоящее время являющаяся стандартном в картографии, геодезии и спутниковой навигации. Согласно этой системе, Земля - эллипсоид, а экватор и нулевой меридиан - опорные точки для широты и долготы соответственно.

‼️ Обязательным условием является работа с изображением карты, которое соответствует WGS 84.

Подходящее изображение карты можно взять, например, здесь.

🚀 Перейдем к решению.

Поскольку точка отсчета - это пересечение экватора и нулевого меридиана, а нам удобнее было бы работать с левым верхним углом изображения, как началом координат, то для смещения по оси X используем ложный сдвиг в восточном направлении, а по оси Y ложный сдвиг в северном направлении. Ложный сдвиг - это линейное значение, применяемое к началу координат, которое позволяет гарантировать, что значения по конкретной оси будут положительными, что нам и нужно при работе с изображением.

Сама формула расчета давно известна, я приведу вариант ее реализации на языке python применительно к задаче, а также чтение и отрисовку тестовых данных с использованием библиотеки opencv.

Тестовые данные
data = [
    {"lat": 55.75, "lon": 37.6, "label": "Moscow"},
    {"lat": 55.0415, "lon": 82.9346, "label": "Novosibirsk"},
    {"lat": 56.8519, "lon": 60.6122, "label": "Yekaterinburg"},
    {"lat": 51.3026, "lon": 0.0739, "label": "London"},
    {"lat": 48.48, "lon": 2.20, "label": "Paris"},
    {"lat": 40.24, "lon": -3.41, "label": "Madrid"},
]


Функция построения проекции
# lat - широта
# lon - долгота
# width - ширина изображения карты
# height - высота изображения карты
def latlon_to_offset(lat, lon, width, height):
    # ложный сдвиг в восточном направлении
    FALSE_EASTING = 180

    # долгота меридиана в точке отсчета
    # 0, т.к. у нас точкой отсчета является левый край карты
    lon0 = 0

    # радиус Земли в проекции
    # ширина изображения здесь является длиной окружности
    radius = width / (2 * math.pi)

    # переводим широту и долготу в радианы
    radian_lat = math.radians(lat)
    radian_lon = math.radians(lon - lon0 + FALSE_EASTING)

    # определяем положение по X
    offset_x = radius * radian_lon

    # определяем положение по Y относительно экватора
    offset_y_from_equator = radius * math.log(math.tan(math.pi / 4 + radian_lat / 2))

    # определяем положение по Y относительно верхней границы изображения
    offset_y = height / 2 - offset_y_from_equator

    return int(offset_x), int(offset_y)


Читаем изображение, применяем функцию на тестовых данных, отрисовываем результат и сохраняем
src = cv2.imread("1084px-Web_maps_Mercator_projection_SW.jpg", cv2.IMREAD_COLOR)
h, w, _ = src.shape

for item in data:
    x, y = latlon_to_offset(item["lat"], item["lon"], w, h)
    src = cv2.circle(src, (x, y), 5, (0, 0, 255), 2)

cv2.imwrite("result.jpg", src)


#python #geo
🔥3
В качестве первого шага цикла разработки системы оценки и фильтрации комментариев в Telegram-каналах опробую несколько готовых моделей для определения токсичности текста, эмоциональной окраски и принадлежности к спаму с площадки Hugging Face.

🌐 Полную версию статьи смотри на сайте, а исходники и тестовые комментарии в репозитории на gitverse.

⚒️ Подготовка
🔹 Для упрощения взаимодействия с моделями была разработана библиотека Transformers с поддержкой Torch. Устанавливаем
pip install transformers torch pandas

🔹 В качестве тестовых данных можно воспользоваться подготовленными датасетами комментариев на русском языке, например, здесь или здесь или же самостоятельно выгрузить комментарии из Telegram-каналов способом, который я озвучивал в одной из предыдущих заметок.

🚀 Применение
Заявленные критерии оценки относятся к задаче классификации текста. Из этого подраздела на Hugging Face и будем выбирать соответствующие модели.

1️⃣ Эмоциональная окраска текста
Используем модель rubert-base-cased-russian-sentiment от частного исследователя
Вячеслава Литвинова. Модель обучена различать 3 класса тональности: нейтральный, позитивный, негативный.
from transformers import pipeline
# объявляем pipeline (высокоуровневая обертка для работы с моделями)
# с указанием задачи text-classification
pipe = pipeline("text-classification", model="seara/rubert-base-cased-russian-sentiment")
# читаем файл с комментариями
with open("comments.txt", mode="r", encoding="utf-8") as f:
comments = [line.rstrip() for line in f.readlines()]
# определяем тональность текста и выводим результат
for comment in comments:
print(f"\nComment: {comment}\nResult: {pipe(comment)}")


Результаты:
Comment: уродина, его так подвесить.
Result: [{'label': 'neutral', 'score': 0.5076143741607666}]
Comment: спасибо что приняли меня
Result: [{'label': 'positive', 'score': 0.69575035572052}]
Comment: твари, живут же такие подленькие людишки
Result: [{'label': 'negative', 'score': 0.5077788233757019}]
Comment: ты как футболный мяч
Result: [{'label': 'neutral', 'score': 0.8442604541778564}]

Стоит отметить наличие сомнений (низкой вероятности) в некоторых результатах из-за неоднозначности интерпретации текста.

2️⃣ Определение токсичности
Применим модель russian_toxicity_classifier от группы s-nlp.
Принцип тот же самый, что и в предыдущем подходе, только указываем другую модель при создании pipeline
pipe = pipeline("text-classification", model="s-nlp/russian_toxicity_classifier")


Результаты:
Comment: уродина, его так подвесить.
Result: [{'label': 'toxic', 'score': 0.9966415166854858}]
Comment: спасибо что приняли меня
Result: [{'label': 'neutral', 'score': 0.999728262424469}]
Comment: твари, живут же такие подленькие людишки
Result: [{'label': 'toxic', 'score': 0.9866997003555298}]
Comment: ты как футболный мяч
Result: [{'label': 'neutral', 'score': 0.9938940405845642}]

Здесь уже уверенности побольше, т.к. классификация бинарная, что несколько упрощает задачу.

3️⃣ Определение спама
Для данного раздела возьмем модель spam_deberta_v4 от группы исследователей RUSpam.
Можно пойти уже проверенным путем и использовать pipeline или загрузить модель напрямую, настроить токенизатор (предобработка текста перед отправкой на модель для классификации) и обработчик результата. Разработчики предлагают второй вариант, воспользуемся.

Результаты:
Comment: быдло оно и в африке быдло!
Result: Не спам
Comment: Уважаемый победитель, вы получили приз в нашей лотерее!
Result: Спам
Comment: Вы стали участником розыгрыша призов: проверьте свою удачу!
Result: Спам
Comment: Привет, как дела? Яблоко
Result: Не спам


Результаты применения одиночных моделей оказались на удивление информативными с учетом того, что предварительно никаких исследований не выполнялось. Не лишним будет провести эксперименты анализа текста по совокупности признаков, формируемых несколькими оценочными моделями, более точно сформулировав задачу и расширив тестовую выборку. Опробованные классификаторы найдут дальнейшее применение в системе фильтрации комментариев в Telegram.

#python #nlp #ml
🔥3