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