TGStat / backend.py
Illioa's picture
Update backend.py
775d05c
import os
import asyncio
from requests_html import AsyncHTMLSession
import logging
import pandas as pd
import streamlit as st
async def get_channels_by_category(category_name,categoriesDict, sub_min):
asession = AsyncHTMLSession()
category_link = categoriesDict[category_name]
logging.info(f'Fetching data from {category_link}')
response = await asession.get(category_link)
channels_list = response.html.find("#category-list-form > div.row.justify-content-center.lm-list-container > div")
channels_data = []
progress_text = "Parsing..."
my_bar = st.progress(0, text=progress_text)
for index,channel in enumerate(channels_list):
channel_name = channel.find('div.font-16.text-dark.text-truncate', first=True).text
Tgstat_link = str(list(channel.absolute_links)[0]) +'/stat'
async def get_values_by_channel(stats_link):
r = await asession.get(stats_link)
r = r.html
subscribers_count = int(r.find("#sticky-center-column > div > div > div:nth-child(1) > div > h2", first=True).text.replace(' ', ''))
chatBlock = r.find("#sticky-center-column > div > div > div > div > div.position-absolute.text-uppercase.text-dark.font-12")
chars = [x.text.replace('\n',' ').capitalize() for x in chatBlock]
allBlocks = r.find('#sticky-center-column > div > div > div > div')
allText = [x.text.split('\n') for x in allBlocks ]
dict_ = dict(zip(chars, allText))
required_columns = ['Подписчики', 'Индекс цитирования','Средний охват 1 публикации','Средний рекламный охват 1 публикации','Возраст канала']
for key in dict_.keys():
if key not in required_columns:
try:
dict_[key]=eval(dict_[key][0].replace(' ', '').replace('всего',' ').replace('%','/100').replace('k','*1000'))
except:
pass
def process_metric(metric, keys, transformations, mainKey):
for i in range(1, len(metric)):
if metric[i] in keys:
key = metric[i].capitalize()
try:
value = round(eval(metric[i - 1].replace(' ', '').replace('%', '/100').replace('k', '*1000')),2) if metric[i] != 'канал создан' else metric[i - 1]
except:
value = None
transformations[f'{mainKey} ({key})'] = value
keys_and_transformations = {
'Подписчики': ['сегодня', 'за неделю', 'за месяц'],
'Индекс цитирования': ['уп. каналов', 'упоминаний', 'репостов'],
'Средний охват 1 публикации': ['ERR', 'ERR24'],
'Средний рекламный охват 1 публикации': ['за 12 часов', 'за 24 часа', 'за 48 часов'],
'Возраст канала': ['канал создан']
}
for key, values in keys_and_transformations.items():
process_metric(dict_[key], values, dict_,key)
for key in dict_.keys():
if key in required_columns and key != 'Возраст канала':
try:
dict_[key]=eval(dict_[key][0].replace(' ', '').replace('всего',' ').replace('%','/100').replace('k','*1000'))
except:
pass
del dict_['Возраст канала']
dict_['TG Link'] = list(r.find('body > div.wrapper > div > div.content.p-0.col > div.container-fluid.px-2.px-md-3 > div:nth-child(2) > div > div > div > div.col-12.col-sm-7.col-md-8.col-lg-6 > div.text-center.text-sm-left > a')[0].absolute_links)[0]
return dict_
subscribers_count = int(channel.find('div.font-12.text-truncate', first=True).text.replace(' подписчиков', '').replace(' ', ''))
if subscribers_count > sub_min:
values = await get_values_by_channel(Tgstat_link)
values['Name'] = channel_name
values['Tgstat_link'] = Tgstat_link
channels_data.append(values)
my_bar.progress((index + 1)/len(channels_list), text=progress_text)
df = pd.DataFrame(channels_data)
df = df.rename(columns={'Возраст канала (Канал создан)': 'Возраст канала'})
df['Категорія'] = category_name
desired_column_order = [
'Name',
'Категорія',
'Подписчики',
'Подписчики (Сегодня)',
'Подписчики (За неделю)',
'Подписчики (За месяц)',
'Индекс цитирования',
'Возраст канала',
'Средний рекламный охват 1 публикации (За 24 часа)',
'TG Link',
'Tgstat_link',
'Индекс цитирования (Уп. каналов)',
'Индекс цитирования (Упоминаний)',
'Индекс цитирования (Репостов)',
'Средний охват 1 публикации',
'Средний охват 1 публикации (Err)',
'Средний охват 1 публикации (Err24)',
'Средний рекламный охват 1 публикации',
'Средний рекламный охват 1 публикации (За 12 часов)',
'Средний рекламный охват 1 публикации (За 48 часов)',
'Публикации',
'Вовлеченность подписчиков (err)',
'Вовлеченность подписчиков (er)',
'Подписки/отписки за 24 часа',
'Пол подписчиков',
'Stories'
]
desired_column_order = [x for x in desired_column_order if x in df.columns]
# Reorder the columns in the DataFrame
df = df[desired_column_order]
# Save the DataFrame to CSV file
# df.to_csv(f'{category_name}.csv', index=False)
return df