Spaces:
Sleeping
Sleeping
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 | |