20204311 《Python程式設計》實驗四:Python綜合實踐——瀏覽記錄分析
阿新 • • 發佈:2021-06-30
簡介
- 實驗名稱:Python綜合實踐——瀏覽記錄分析
- 課程:《Python程式設計》
- 班級: 2043
- 姓名: 曲經民
- 學號:20204311
- 實驗教師:王志強
- 實驗日期:2021年6月
- 必修/選修: 選修課
實驗內容
之前我在翻找瀏覽器歷史記錄的時候發現,單獨查詢某一天的記錄很方便,但是綜合分析一段時間的瀏覽記錄就比較困難。通過查詢得知,Chrome瀏覽器的歷史記錄資料儲存在名為History的sqlite資料庫檔案中。
所以我打算通過python編寫一個能夠分析一段時間內瀏覽記錄的程式,並且通過圖表的形式將分析結果展示在網頁上,分析結果包括瀏覽時間、次數、搜尋引擎偏好等等。
實驗要求
(1)程式能執行,功能豐富。(需求提交原始碼,並建議錄製程式執行的視訊) (2)綜合實踐報告,要體現實驗分析、設計、實現過程、結果等資訊,格式規範,邏輯清晰,結構合理。 (3)在實踐報告中,需要對全課進行總結,並寫課程感想體會、意見和建議等。
實驗過程及結果
一. 實現應用的關鍵步驟設計
二. 程式碼編寫及除錯執行
1. 解析歷史記錄檔案資料
與解析歷史記錄檔案資料有關的檔案為history_data.py
檔案。
# 連線sqlite資料庫,執行查詢語句,返回查詢結構,最終關閉資料庫連線。 def query_sqlite_db(history_db, query): # 查詢sqlite資料庫 conn = sqlite3.connect(history_db) cursor = conn.cursor() select_statement = query cursor.execute(select_statement) # 獲取資料,資料格式為元組(tuple) results = cursor.fetchall() cursor.close() conn.close() return results # 設定資料庫查詢語句select_statement,呼叫query_sqlite_db()函式,獲取解析後的歷史記錄檔案資料。並對返回後的歷史記錄資料檔案按照不同元素規則進行排序。 def get_history_data(history_file_path): try: select_statement = "SELECT urls.id, urls.url, urls.title, urls.last_visit_time, urls.visit_count, visits.visit_time, visits.from_visit, visits.transition, visits.visit_duration FROM urls, visits WHERE urls.id = visits.url;" result = query_sqlite_db(history_file_path, select_statement) # 將結果按第1個元素進行排序 result_sort = sorted(result, key=lambda x: (x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8])) # 返回排序後的資料 return result_sort except: # print('讀取出錯!') return 'error'
至此,成功獲取經過排序的解析後的瀏覽記錄資料檔案。
2. web伺服器基本配置
與web伺服器基本配置有關的檔案為app_configuration.py
和app.py
檔案。
本專案使用dash框架。
dash是一款基於python的web輕量級框架,無需js即可輕鬆執行。
適合用於比較簡單的web頁面的快速部署,如資料視覺化,圖表展示等。
import dash # 配置一個dash伺服器 app = dash.Dash(__name__) #設定web伺服器的埠號,訪問許可權,靜態資源目錄等 # 設定網頁標題 app.title = 'Browser History Analysis' # 開啟載入本地css和js檔案模式 app.css.config.serve_locally = True app.scripts.config.serve_locally = True app.layout = app_layout # 回撥,用於更新web頁面資料 app_callback_function() # 開始執行web伺服器 if __name__ == '__main__': # 是否是在本地執行(測試) app_local = False if(app_local): app.run_server(host='127.0.0.1', debug=True, port='8090') else: app.run_server(host='0.0.0.0', debug=False, port='8090')
3. 前端頁面部署
與前端部署有關的檔案為app_layout.py
和app_plot.py
以及assets
目錄。
在app_layout.py
中,配置的元件和平常的html, css大多一樣,這裡以配置頁面訪問次數排名元件為例。
# 頁面訪問次數排名
html.Div(
style={'margin-bottom':'150px'},
children=[
html.Div(
style={'border-top-style':'solid','border-bottom-style':'solid'},
className='row',
children=[
html.Span(
children='頁面訪問次數排名, ',
style={'font-weight': 'bold', 'color':'red'}
),
html.Span(
children='顯示個數:',
),
dcc.Input(
id='input_website_count_rank',
type='text',
value=10,
style={'margin-top':'10px', 'margin-bottom':'10px'}
),
]
),
html.Div(
style={'position': 'relative', 'margin': '0 auto', 'width': '100%', 'padding-bottom': '50%', },
children=[
dcc.Loading(
children=[
dcc.Graph(
id='graph_website_count_rank',
style={'position': 'absolute', 'width': '100%', 'height': '100%', 'top': '0',
'left': '0', 'bottom': '0', 'right': '0'},
config={'displayModeBar': False},
),
],
type='dot',
style={'position': 'absolute', 'top': '50%', 'left': '50%', 'transform': 'translate(-50%,-50%)'}
),
],
)
]
)
在app_plot.py
中,使用plotly
庫繪製圖表。plotly
庫是一個用於具有web互動功能的畫圖元件庫。
# 繪製 頁面訪問頻率排名 柱狀圖
def plot_bar_website_count_rank(value, history_data):
# 頻率字典
dict_data = {}
# 對歷史記錄檔案進行遍歷
for data in history_data:
url = data[1]
# 簡化url
key = url_simplification(url)
if (key in dict_data.keys()):
dict_data[key] += 1
else:
dict_data[key] = 0
# 篩選出前k個頻率最高的資料
k = convert_to_number(value)
top_10_dict = get_top_k_from_dict(dict_data, k)
figure = go.Figure(
data=[
go.Bar(
x=[i for i in top_10_dict.keys()],
y=[i for i in top_10_dict.values()],
name='bar',
marker=go.bar.Marker(
color='rgb(55, 83, 109)'
)
)
],
layout=go.Layout(
showlegend=False,
margin=go.layout.Margin(l=40, r=0, t=40, b=30),
paper_bgcolor='rgba(0,0,0,0)',
plot_bgcolor='rgba(0,0,0,0)',
xaxis=dict(title='網站'),
yaxis=dict(title='次數')
)
)
return figure
該函式的程式碼流程為:
- 首先,對解析完資料庫檔案後返回的
history_data
進行遍歷,獲得url
資料,並呼叫url_simplification(url)
對齊進行簡化。接著,依次將簡化後的url
存入字典中。 - 呼叫
get_top_k_from_dict(dict_data, k)
,從字典dict_data
中獲取前k
個最大值的資料。 - 接著,開始繪製柱狀圖。使用
go.Bar()
繪製柱狀圖,其中,x
和y
代表的是屬性和屬性對應的數值,為list
格式。
xaxis和
yaxis`分別設定相應座標軸的標題。 - 返回一個
figure
物件,以便於傳輸給前端。
assets
目錄下包含的資料為css
,用於前端佈局。
4. 後臺部署
與後臺部署有關的檔案為app_callback.py
檔案。這個檔案使用回撥的方式對前端頁面佈局進行更新。
以頁面訪問頻率排名的回撥函式為例:
#頁面訪問頻率排名的回撥函式
@app.callback(
dash.dependencies.Output('graph_website_count_rank', 'figure'),
[
dash.dependencies.Input('input_website_count_rank', 'value'),
dash.dependencies.Input('store_memory_history_data', 'data')
]
)
def update(value, store_memory_history_data):
# 正確獲取到歷史記錄檔案
if store_memory_history_data:
history_data = store_memory_history_data['history_data']
figure = plot_bar_website_count_rank(value, history_data)
return figure
else:
# 取消更新頁面資料
raise dash.exceptions.PreventUpdate("cancel the callback")
該函式的程式碼流程為:
- 首先確定好輸入是什麼(觸發回撥的資料),輸出是什麼(回撥輸出的資料),需要帶上什麼資料。
dash.dependencies.Input
指的是觸發回撥的資料,而dash.dependencies.Input('input_website_count_rank', 'value')
表示當id
為input_website_count_rank
的元件的value
發生改變時,會觸發這個回撥。而該回調經過update(value, store_memory_history_data)
的結果會輸出到id
為graph_website_count_rank
的value
。 - 對於
def update(value, store_memory_history_data)
的解析。首先是判斷輸入資料store_memory_history_data
是否不為空物件,接著讀取歷史記錄檔案history_data
,接著呼叫剛才所說的app_plot.py
檔案中的plot_bar_website_count_rank()
,返回一個figure
物件,並將這個物件返回到前端。至此,前端頁面的佈局就會顯示出頁面訪問頻率排名
的圖表了。
接下來,就是從Chrome歷史記錄檔案中提取出想要的資料。由於Chrome歷史記錄檔案是一個sqlite資料庫,所以需要使用資料庫語法提取出相關內容。
# 獲取排序後的歷史資料
def get_history_data(history_file_path):
try:
select_statement = "SELECT urls.id, urls.url, urls.title, urls.last_visit_time, urls.visit_count, visits.visit_time, visits.from_visit, visits.transition, visits.visit_duration FROM urls, visits WHERE urls.id = visits.url;"
result = query_sqlite_db(history_file_path, select_statement)
# 將結果按第1個元素進行排序
result_sort = sorted(result, key=lambda x: (x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8]))
return result_sort
except:
# print('讀取出錯!')
return 'error'
每個欄位代表的意思:
欄位名 | 含義 |
---|---|
urls.id | url的編號 |
urls.url | url的地址 |
urls.title | url的標題 |
urls.last_visit_time | url的最後訪問時間 |
urls.visit_count | url的訪問次數 |
urls.visit_time | url的訪問時間 |
urls.from_visit | 從哪裡訪問到這個url |
urls.transition | url的跳轉 |
urls.visit_duration | url的停留時間 |
5.程式碼調式及執行
執行成功後,通過瀏覽器開啟http://localhost:8090:
上傳瀏覽器History檔案後,即可看到分析結果:
三. 將程式碼上傳碼雲
實驗中遇到的問題
本次實驗中我遇到了很多問題。例如由於Chrome瀏覽器在sqlite中儲存的時間是以1601-01-01 00:00:00 為起始時間點的微妙計數,與Unix時間戳存在時間間隔,所以需要轉換,這給我造成了很大困擾。
但通過查詢相關資料,我最終解決了這些問題,這也是對我綜合實踐能力的一次提升。