Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -5,15 +5,14 @@ import json
|
|
| 5 |
from requests_html import AsyncHTMLSession
|
| 6 |
import streamlit as st
|
| 7 |
|
| 8 |
-
asession = AsyncHTMLSession()
|
| 9 |
-
|
| 10 |
async def get_dict_topic():
|
|
|
|
| 11 |
response = await asession.get('https://uk.tgstat.com/')
|
| 12 |
category_block = response.html.find('body > div.wrapper > div > div.content.p-0.col > div.container-fluid.px-2.px-md-3 > div:nth-child(5) > div > div.card.border.m-0 > div')
|
| 13 |
category_links = list(category_block[0].absolute_links)
|
| 14 |
category_names = []
|
| 15 |
|
| 16 |
-
for category_link in category_links:
|
| 17 |
try:
|
| 18 |
response = await asession.get(category_link)
|
| 19 |
name = response.html.find("h1", first=True).text
|
|
@@ -23,20 +22,18 @@ async def get_dict_topic():
|
|
| 23 |
|
| 24 |
return dict(zip(category_names, category_links))
|
| 25 |
|
| 26 |
-
if not os.path.exists('categories.json'):
|
| 27 |
-
categoriesDict = asyncio.get_event_loop().run_until_complete(get_dict_topic())
|
| 28 |
-
with open('categories.json', 'w') as f:
|
| 29 |
-
f.write(json.dumps(categoriesDict))
|
| 30 |
-
|
| 31 |
async def get_channels_by_category(category_name):
|
|
|
|
| 32 |
with open('categories.json', 'r') as f:
|
| 33 |
-
categoriesDict =
|
| 34 |
category_link = categoriesDict[category_name]
|
| 35 |
|
|
|
|
|
|
|
| 36 |
response = await asession.get(category_link)
|
| 37 |
channels_list = response.html.find("#category-list-form > div.row.justify-content-center.lm-list-container > div")
|
| 38 |
channels_data = []
|
| 39 |
-
for channel in channels_list:
|
| 40 |
channel_name = channel.find('div.font-16.text-dark.text-truncate', first=True).text
|
| 41 |
Tgstat_link = str(list(channel.absolute_links)[0]) +'/stat'
|
| 42 |
|
|
@@ -52,8 +49,8 @@ async def get_channels_by_category(category_name):
|
|
| 52 |
dict_ = dict(zip(chars, allText))
|
| 53 |
required_columns = ['Подписчики', 'Индекс цитирования','Средний охват 1 публикации','Средний рекламный охват 1 публикации','Возраст канала']
|
| 54 |
for key in dict_.keys():
|
| 55 |
-
|
| 56 |
-
|
| 57 |
|
| 58 |
def process_metric(metric, keys, transformations, mainKey):
|
| 59 |
for i in range(1, len(metric)):
|
|
@@ -73,23 +70,55 @@ async def get_channels_by_category(category_name):
|
|
| 73 |
for key, values in keys_and_transformations.items():
|
| 74 |
process_metric(dict_[key], values, dict_,key)
|
| 75 |
|
|
|
|
| 76 |
for key in dict_.keys():
|
| 77 |
-
|
| 78 |
-
|
| 79 |
|
| 80 |
del dict_['Возраст канала']
|
| 81 |
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]
|
| 82 |
return dict_
|
| 83 |
|
|
|
|
| 84 |
subscribers_count = int(channel.find('div.font-12.text-truncate', first=True).text.replace(' подписчиков', '').replace(' ', ''))
|
| 85 |
if subscribers_count > 10000:
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
|
|
|
| 90 |
df = pd.DataFrame(channels_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
return df
|
| 92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
def fetch_data(selected_category):
|
| 94 |
loop = asyncio.new_event_loop()
|
| 95 |
asyncio.set_event_loop(loop)
|
|
|
|
| 5 |
from requests_html import AsyncHTMLSession
|
| 6 |
import streamlit as st
|
| 7 |
|
|
|
|
|
|
|
| 8 |
async def get_dict_topic():
|
| 9 |
+
asession = AsyncHTMLSession()
|
| 10 |
response = await asession.get('https://uk.tgstat.com/')
|
| 11 |
category_block = response.html.find('body > div.wrapper > div > div.content.p-0.col > div.container-fluid.px-2.px-md-3 > div:nth-child(5) > div > div.card.border.m-0 > div')
|
| 12 |
category_links = list(category_block[0].absolute_links)
|
| 13 |
category_names = []
|
| 14 |
|
| 15 |
+
for category_link in tqdm(category_links, desc='Fetching Categories', ncols=100):
|
| 16 |
try:
|
| 17 |
response = await asession.get(category_link)
|
| 18 |
name = response.html.find("h1", first=True).text
|
|
|
|
| 22 |
|
| 23 |
return dict(zip(category_names, category_links))
|
| 24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
async def get_channels_by_category(category_name):
|
| 26 |
+
asession = AsyncHTMLSession()
|
| 27 |
with open('categories.json', 'r') as f:
|
| 28 |
+
categoriesDict = eval(f.read())
|
| 29 |
category_link = categoriesDict[category_name]
|
| 30 |
|
| 31 |
+
logging.info(f'Fetching data from {category_link}')
|
| 32 |
+
|
| 33 |
response = await asession.get(category_link)
|
| 34 |
channels_list = response.html.find("#category-list-form > div.row.justify-content-center.lm-list-container > div")
|
| 35 |
channels_data = []
|
| 36 |
+
for channel in tqdm(channels_list, desc=f'Fetching Channels for {category_name}', ncols=100):
|
| 37 |
channel_name = channel.find('div.font-16.text-dark.text-truncate', first=True).text
|
| 38 |
Tgstat_link = str(list(channel.absolute_links)[0]) +'/stat'
|
| 39 |
|
|
|
|
| 49 |
dict_ = dict(zip(chars, allText))
|
| 50 |
required_columns = ['Подписчики', 'Индекс цитирования','Средний охват 1 публикации','Средний рекламный охват 1 публикации','Возраст канала']
|
| 51 |
for key in dict_.keys():
|
| 52 |
+
if key not in required_columns:
|
| 53 |
+
dict_[key]=eval(dict_[key][0].replace(' ', '').replace('всего',' ').replace('%','/100').replace('k','*1000'))
|
| 54 |
|
| 55 |
def process_metric(metric, keys, transformations, mainKey):
|
| 56 |
for i in range(1, len(metric)):
|
|
|
|
| 70 |
for key, values in keys_and_transformations.items():
|
| 71 |
process_metric(dict_[key], values, dict_,key)
|
| 72 |
|
| 73 |
+
|
| 74 |
for key in dict_.keys():
|
| 75 |
+
if key in required_columns and key != 'Возраст канала':
|
| 76 |
+
dict_[key]=eval(dict_[key][0].replace(' ', '').replace('всего',' ').replace('%','/100').replace('k','*1000'))
|
| 77 |
|
| 78 |
del dict_['Возраст канала']
|
| 79 |
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]
|
| 80 |
return dict_
|
| 81 |
|
| 82 |
+
|
| 83 |
subscribers_count = int(channel.find('div.font-12.text-truncate', first=True).text.replace(' подписчиков', '').replace(' ', ''))
|
| 84 |
if subscribers_count > 10000:
|
| 85 |
+
values = await get_values_by_channel(Tgstat_link)
|
| 86 |
+
values['Name'] = channel_name
|
| 87 |
+
values['Tgstat_link'] = Tgstat_link
|
| 88 |
+
|
| 89 |
+
channels_data.append(values)
|
| 90 |
df = pd.DataFrame(channels_data)
|
| 91 |
+
df = df.rename(columns={'Возраст канала (Канал создан)': 'Канал создан'})
|
| 92 |
+
df['Канал создан'] = pd.to_datetime(df['Канал создан'], format='%d.%m.%Y', errors='coerce')
|
| 93 |
+
desired_column_order = [
|
| 94 |
+
'Name', 'TG Link', 'Tgstat_link','Канал создан',
|
| 95 |
+
'Подписчики', 'Индекс цитирования', 'Средний охват 1 публикации',
|
| 96 |
+
'Средний рекламный охват 1 публикации', 'Публикации',
|
| 97 |
+
'Вовлеченность подписчиков (err)', 'Вовлеченность п��дписчиков (er)',
|
| 98 |
+
'Подписчики (Сегодня)', 'Подписчики (За неделю)',
|
| 99 |
+
'Подписчики (За месяц)', 'Индекс цитирования (Уп. каналов)',
|
| 100 |
+
'Индекс цитирования (Упоминаний)', 'Индекс цитирования (Репостов)',
|
| 101 |
+
'Средний охват 1 публикации (Err)',
|
| 102 |
+
'Средний охват 1 публикации (Err24)',
|
| 103 |
+
'Средний рекламный охват 1 публикации (За 12 часов)',
|
| 104 |
+
'Средний рекламный охват 1 публикации (За 24 часа)',
|
| 105 |
+
'Средний рекламный охват 1 публикации (За 48 часов)',
|
| 106 |
+
'Подписки/отписки за 24 часа',
|
| 107 |
+
'Пол подписчиков', 'Stories'
|
| 108 |
+
]
|
| 109 |
+
|
| 110 |
+
# Reorder the columns in the DataFrame
|
| 111 |
+
df = df[desired_column_order]
|
| 112 |
+
|
| 113 |
+
# Save the DataFrame to CSV file
|
| 114 |
+
df.to_csv(f'{category_name}.csv', index=False)
|
| 115 |
return df
|
| 116 |
|
| 117 |
+
if not os.path.exists('categories.json'):
|
| 118 |
+
categoriesDict = asyncio.get_event_loop().run_until_complete(get_dict_topic())
|
| 119 |
+
with open('categories.json', 'w') as f:
|
| 120 |
+
f.write(json.dumps(categoriesDict))
|
| 121 |
+
|
| 122 |
def fetch_data(selected_category):
|
| 123 |
loop = asyncio.new_event_loop()
|
| 124 |
asyncio.set_event_loop(loop)
|