计算机硬件综合实践实验报告,20204311《Python程序设计》实验四 Python综合实践实验报告...

简介

实验名称:Python综合实践——浏览记录分析

课程:《Python程序设计》

班级: 2043

姓名: 曲经民

学号:20204311

实验教师:王志强

实验日期:2021年6月

必修/选修: 选修课

实验内容

之前我在翻找浏览器历史记录的时候发现,单独查询某一天的记录很方便,但是综合分析一段时间的浏览记录就比较困难。通过查询得知,Chrome浏览器的历史记录数据存储在名为History的sqlite数据库文件中。

所以我打算通过python编写一个能够分析一段时间内浏览记录的程序,并且通过图表的形式将分析结果展示在网页上,分析结果包括浏览时间、次数、搜索引擎偏好等等。

实验要求

(1)程序能运行,功能丰富。(需求提交源代码,并建议录制程序运行的视频)

(2)综合实践报告,要体现实验分析、设计、实现过程、结果等信息,格式规范,逻辑清晰,结构合理。

(3)在实践报告中,需要对全课进行总结,并写课程感想体会、意见和建议等。

实验过程及结果

一. 实现应用的关键步骤设计

92950ff23ba110e4dc2e30f6200ae9d5.png

二. 代码编写及调试运行

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.代码调式及运行

26b68b0bb64cb67313a79d453dfb5417.png

运行成功后,通过浏览器打开http://localhost:8090:

f1a7c8540dc6e0a3406b3e9716136563.png

上传浏览器History文件后,即可看到分析结果:

9474a61163dc02ed9bbd0647b8d70f27.png

9fb7a345ef076db3c5919d6e313384a9.png

三. 将代码上传码云

d294a95dfcefed9795d132b4ac7d6e86.png

实验中遇到的问题

本次实验中我遇到了很多问题。例如由于Chrome浏览器在sqlite中存储的时间是以1601-01-01 00:00:00 为起始时间点的微妙计数,与Unix时间戳存在时间间隔,所以需要转换,这给我造成了很大困扰。

但通过查询相关资料,我最终解决了这些问题,这也是对我综合实践能力的一次提升。

思想感悟

这学期很幸运地选到了志强老师的Python课。我一开始以为在Python理论课上,应该就是老师照着PPT念(古板印象),同学们在底下各干各的。但是出乎意料的是,志强老师的理论课十分有趣,理论课也需要我们带着电脑跟着一起敲代码,不仅如此,志强老师的课上也会联系其他知识,例如知识点在实际项目中的应用、与其他编程语言的对比。其中令我印象深刻的是,志强老师在讲到序列的时候,用了王者荣耀英雄的案例,一下子感觉很熟悉(亲切)。

除此以外,课程的实验也设置得十分合理,有层次地由易到难、由浅到深,让我在每次实验过程中都能有全新的收获。正如志强老师在课程之初提到的“人生苦短,我用Python”,通过课程学习,我有了更深的体会。希望编程语言在我们日常生活中应该更多地被使用,这才是编程解决实际问题的魅力所在。

最后,再次感谢志强老师的教导,希望Python课程能越办越好!!!

原文:https://www.cnblogs.com/jam12138/p/14956750.html

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值