123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- """
- 目的:
- 流量週報圖表自動化更新,可以往回查詢。
- 參考:
- ECHARTS: https://echarts.apache.org/zh/tutorial.html#5%20%E5%88%86%E9%92%9F%E4%B8%8A%E6%89%8B%20ECharts
- templates: https://fastapi.tiangolo.com/advanced/templates/
- """
- from fastapi import FastAPI, Request
- from fastapi.responses import HTMLResponse
- from fastapi.staticfiles import StaticFiles
- from fastapi.templating import Jinja2Templates
- import dataset
- import numpy as np
- import pandas as pd
- from starlette.responses import Response
- from pprint import pprint
- app = FastAPI()
- app.mount("/static", StaticFiles(directory="static"), name="static")
- templates = Jinja2Templates(directory="templates")
- WEEK_NUM = 31
- def update_weekly_data():
- """
- 一週更新一次。
- """
- pass
- def get_hhh_weekly_data():
- """ 取得此table的資料作為後續畫圖使用。 """
- db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/hhh?charset=utf8mb4')
- table = db['hhh_weekly_report']
- df = pd.DataFrame(table)
- int_columns = ['id', 'ga:users', 'ga:newusers', 'ga:sessions', 'ga:pageviews', 'ga:isoWeek']
- float_columns = ['ga:bounceRate', 'ga:pageviewsPerSession']
- str_columns = ['category']
- for column in int_columns:
- df[column] = df[column].apply(func=lambda x: int(x))
- for column in float_columns:
- df[column] = df[column].apply(func=lambda x: float(x))
- for column in str_columns:
- df[column] = df[column].apply(func=lambda x: str(x))
- return df
- def get_dates(df, weeknum):
- """ 從df得到當週日期當作X-axis給Echart使用。 """
- dates = df[df['ga:isoWeek'] == weeknum]['ga:date']
- return sorted(list(set(dates)))
- def get_users(df, category='organic', weeknum=26, is_new=True):
- if is_new:
- users = df[(df['category'] == category) & (df['ga:isoWeek'] == weeknum)]['ga:users']
- else:
- users = df[(df['category'] == category) & (df['ga:isoWeek'] == weeknum)]['ga:newusers']
- return list(users)
- ##########################
- df = get_hhh_weekly_data()
- dates = get_dates(df, 25)
- users_social = get_users(df, 'organic', 25, True)
- print(df)
- print(dates)
- print(users_social)
- db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/hhh?charset=utf8mb4')
- query = f"""
- select
- A.query, A.clicks, A.ctr, A.impressions, A.weeknum,
- B.weeknum as last_wk_weeknum, B.clicks as last_wk_clicks, B.ctr as last_wk_ctr, B.impressions as last_wk_impressions,
- ((A.clicks-B.clicks) / B.clicks)*100 as clicks_growth
- from
- ((select query, clicks, ctr, impressions, weeknum
- from hhh.hhh_weekly_keywords
- where weeknum={WEEK_NUM+1} and clicks >=5) as A
- inner join (select query, clicks, ctr, impressions, weeknum from hhh.hhh_weekly_keywords where weeknum={WEEK_NUM} and clicks >= 5) as B
- on A.query=B.query)
- order by
- clicks_growth desc
- limit 20;
- """
- keywords_data = db.query(query)
- keywords_data = pd.DataFrame(keywords_data, columns=['query', 'clicks', 'ctr', 'impressions', 'weeknum', 'p_weeknum', 'p_clicks', 'p_ctr', 'p_impressions', 'clicks_growth'])
- # keywords_data = pd.read_csv('keywords_growth_ckover5.csv')
- print(keywords_data)
- ###########################
- @app.get('/', response_class=HTMLResponse)
- def index(request: Request):
- return templates.TemplateResponse(
- name='index.html',
- context={'request': request, 'dates': dates, 'users': users_social, 'keywords_table_html': keywords_data.to_html()}
- )
- # 要改
- @app.get('/keywords/table/{weeknum}', response_class=HTMLResponse) # https://fastapi.tiangolo.com/advanced/custom-response/
- def get_keywords_table(weeknum: int, request: Request, response: Response):
- resp = keywords_data.copy()
- resp.index = range(1, len(resp)+1)
- resp = resp[['query', 'clicks_growth', 'ctr', 'clicks', 'impressions']]
- resp.loc[:, 'clicks_growth'] = resp.loc[:, 'clicks_growth'].apply(func=lambda x: '{:.2f}'.format(x))
- resp.loc[:, 'ctr'] = resp.loc[:, 'ctr'].apply(func=lambda x: str(round(x*100, 4))[:str(x).index('.')+4] + ' %')
-
- pprint(request)
- pprint(response)
- return resp.to_html(justify='center')
- @app.get('/users/{category}/{weeknum}/{is_new}')
- def get_users_data(category: str, weeknum: int, is_new: bool):
- dates = get_dates(df, weeknum)
- users = get_users(df, category, weeknum, is_new)
- return {
- 'dates': dates,
- 'users': users
- }
- @app.get('/users/{weeknum}')
- def get_users_overview(weeknum: int):
- dates = get_dates(df, weeknum)
- organic_newusers = get_users(df, 'organic', weeknum, True)
- organic_users = get_users(df, 'organic', weeknum, False)
- social_newusers = get_users(df, 'social', weeknum, True)
- social_users = get_users(df, 'social', weeknum, False)
- return {
- 'dates': dates,
- 'organic_newusers': organic_newusers,
- 'organic_users': organic_users,
- 'social_newusers': social_newusers,
- 'social_users': social_users
- }
- @app.get('/keywords/{weeknum}')
- def get_keywords_sorted(weeknum: int):
- keywords = list(keywords_data.loc[:, 'query'])
- # print(keywords)
- keywords_growth = list(keywords_data.loc[:, 'clicks_growth'])
-
- return {'keywords': keywords, 'keywords_growth': keywords_growth}
|