Python构建web应用(进阶版)->对网页HTML优化逻辑显示

本篇是承接上一篇web应用(入门级)的内容往下顺延的,阅读后将会了解HTML逻辑显示优化,如下图所示,从杂乱无章的日志文件到一个整齐的列表显示。

—————————————————————————— 我是分割线 —————————————————————————————————

6存储和管理数据

在下面的内容之前需要了解存储和管理数据的知识。

关于web应用,应该记录每个web请求的数据。这样有利于分析这些问题:

已经响应了多少个请求?最常用的字母列表是什么?请求来自哪个IP地址?哪个浏览器用的最多?……

打开、处理(process)和关闭文件

1.建立一个txt空文件(hh.txt),指定一个变量(a)打开这个文件,后面参数‘a’的含义是采用追加模式打开这个文件。open会返回一个流,赋值给a变量

2.然后打印消息到文件流。

3.完成工作,最后关闭,文件流进行清理。

4.读是open的默认模式,所以不需要提供模式参数,打开文件时仍需要指定一个变量(read),然后open会返回一个文件流赋给read变量。

5.for循环每次循环读取一个数据行,没有数据行即终止。

6.工作完成,关闭文件流进行清理。

访问模式:(r w主要针对文本文件)


访问模式


说明


r


以只读方式打开文件,文件的指针会放在文件的开头。(默认模式)


w


以可写方式打开文件,文件存在时:覆盖,不存在时:创建新文件。


a


以追加方式打开文件,文件存在:指针放在文件结尾,不存在时:创建新文件进行写入。


rb


以二进制格式打开一个文件用于只读。


wb


以可读方式打开二进制文件。


ab


以追加方式打开二进制文件。


r+


打开一个文件用于读写,文件指针在开头。


rb+


wb+


以二进制格式打开一个文件用于只读。


ab+


x


打开一个新文件进行写数据,如果文件存在则失败。

上表没有写全,规律:r--read; w--write; a--add to; b--binary; + --读写

使用with对文件操作

with open(‘hh.txt‘) as a:
  for chore in a:
    print(chore, end = ‘ ‘)

这样可以完成和之前的open相同的操作,并且后面不用close()关闭文件。这些内容是在Python内部有一个上下文管理协议,它完成收尾的工作,在需要时调用close。

之前提到的程序可以在添加内容了,我们想对这个web应用的数据进行存储记录下来。

回顾之前的程序内容:

在下面添加一个函数

def log_request(req: ‘flask_request‘, res: str) -> None:
    with open(‘vsearch.log‘, ‘a‘) as log:
        print(req, res, file=log)

调用这个函数时,req参数作为当前的flask请求对象,res参数作为调用vsearch_for_letters函数的结果.然后函数log_request把req和res的值追加到一个名为vsearch.log的文件。

使用这个函数时,我们添加到上面的do_search中进行调用,当然在调用之前需要定义函数,所以调整位置后的程序如下:

保存后在webapp文件夹中运行cmd,输入python vsearch_for_web.py

然后打开浏览器输入地址http://127.0.0.1:5000进行测试,试过几次之后会发现生成了一个log文件

通过web应用查看日志

下来让日志显示在web浏览器里,所以新建一个URL: /viewlog

在最后面添加代码:

@app.route(‘/viewlog‘)
  def view_the_log() -> str:
    with open(‘vsearch.log‘) as log:
      contents = log.read()
  return contents

保存测试后键入http://127.0.0.1:5000/viewlog看到:

这些好像只是浏览器接受和显示最后的结果,并没有最开始搜索的内容,检查网页的源代码,直接浏览器中右键

这些内容和刚才的并没有太大差别,还是没有看到搜索的内容,web拒绝显示用户搜索的数据,因为HTML中<Request>是一个不合法的标记,浏览器会将它忽略。

转义数据

Flask包含一个escape函数,调用时提供一个字符串,其中不包含任何特殊字符:

对一些包含特殊字符的字符串使用这个函数,它会将<>转义为&lt和&gt

在第一行调用加入escape然后在后面的return后使用函数:escape(contents)

新的测试结果:

注意到刚才是红色的字变成了黑色字,,不过这些数字并不能看出来什么。

更改代码:

只在最后的print做了修改,把req的内容通过dir()列出然后转成字符输出。

下来测试新的日志记录代码,先完成下列步骤:

  1. 修改log_request与上图保持一致。
  2. 保存修改后的代码,这回重启我们的web应用。
  3. 找到并删除当前的vsearch.log文件。
  4. 通过浏览器输入3个新搜索。
  5. 使用/viewlog查看新创建的日志。

仔细看看现在的内容,有意义了吗?

这似乎有些乱,不过仔细看会发现有一些我们查找到的值。

现在可以看到每个请求都有大量的关联方法和属性,记录所有的属性是没有意义的。其中有三个对于日志记录很重要:

  • req.form:从web应用的HTML表单提交的数据。
  • req.remote_addr:运行web浏览器的IP地址。
  • req.user_agent:提交数据的浏览器标识。

下面对代码进行进一步的调整。

记录特定的web请求属性

分别输出这些内容,end=‘|’表示把默认的换行符替换为|,这样一个请求的数据就是一行内容。

这是新的日志文件的内容:可以看到数据都在一行而且整齐了很多

上文中的连续四个print好像有些多余,其实可以缩减到一个print语句中,有一个可选的参数sep,它可以设置分隔符,默认为空格。

下来改进那几行print代码:

def log_request(req: ‘falsk请求‘, res: str) -> None:
  with open(‘vsearch.log‘, ‘a‘) as log:
    print(req.form, req.remote_addr, req.user_agent, res, file=log, sep=‘|‘)

继续刚才那五个步骤,就是重新测试的步骤。提示:存代码、删日志、新键入。

然后查看URL:/viewlog会发现少了很多

可以找到里面有搜索的字符串也有结果,看来已经有意义了。可是如何更加规范这些内容呢?

从原始数据到可读的输出

下面是vsearch.log文件中的一个数据行:

ImmutableMultiDict([(‘phrase‘, ‘this is s test of the posting capability‘), (‘letters‘, ‘aeiou‘)])|127.0.0.1|Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36|{‘o‘, ‘a‘, ‘e‘, ‘i‘}

三个|分割了四部分内容,第一部分是表单数据。第二部分是远程机器的IP地址。第三部分是web浏览器的标识字符串。最后一部分是函数调用的结果。

  • 使用join可以将列表转换成字符串。

下来在>>>中进行测试:

join前面的‘|’意思是使用|将每个字符串连接起来。

  • 而split是将字符串转换成列表。

使用给定的|,将字符串分割成一个列表。

修改代码:

使用文件打开的open命令,用|将日志中的记录转换成一个列表,这样会看起来更加美观,可读性强。

需要修改的是view_the_log函数。

def view_the_log() -> str:
  contents = []
  with open(‘vsearch.log‘) as log:
    for lines in log:
      contents.append([])
      for item in lines.split(‘|‘):
        contents[-1].append(escape(item))
  return escape(contents)

有一些地方需要解释:

也许你会对contents[-1].append(escape(item))有疑问,理解这行代码技巧从内向外、从左向右读。首先是外围for循环的item开始,它会传递到escape,在用append将得到的字符串追加到contents末尾 ( [-1] ) 。contents是一个嵌套列表。

保存代码然后进行测试:

现在的输出变成了一个嵌套列表,而不再是一个字符串列表。现在我们使用一个设计的jinja2模板处理contents,就基本能得到所需的可读的输出了。

用HTML生成可读的输出

HTML提供了一组标记来定义表格的内容:包括<table>:一个表格,<th>:一行表格数据,<tr>:一个表格列标题和<td>:一个表格数据项(单元格)。

每个标记都有对应的一个结束标记</table>,</tr>,</th>和<td>。

如果发现需要生成HTML,就应该使用jinja2模板引擎,它主要是设计用来生成HTML,这个引擎包含一些基本的编程构造,可以用来“自动实现”需要的显示逻辑。

下面是一个新模板下载的地址还是之前的http://python.itcarlow.ie/ed2/,名为viewlog.html,它可以将日志文件中的原始数据转换成一个HTML表格,这个模板希望传入contents嵌套列表作为他的参数。jinja2的for循环构造与Python类似,但需要注意的是行尾不需要冒号,因为%}相当于一个分隔符;每个循环的代码组用{% endfor %}结束。

可以看到,第一个for循环希望在一个名为the_row_titles的变量中查找数据,而第二个for循环希望得到the_data中的数据。第三个for循环希望数据是一个数据项列表。

整个表在一个<table>标记中,描述性标题<th>中有单独的行<tr>标记。每个日志数据项放在一个<td>标记中,日志文件中的各行有单独的<tr>标记。(现在可能有些困难,不过后面就会理解这几句话的含义)

这个模板需要放在templates文件夹下面。

要让viewlog.html调用render_template(render_template的函数,如果指定一个模板名和所需的参数,调用这个函数时会返回一个HTML串。),为它需要的三个参数分别传入值。下面创建一个描述性的标题元组,并把它赋值给the_row_titles,然后将contents的值赋给the_data。在呈现这个模板之前,还需要给the_title提供一个适当的值,修改函数view_the_log:

def view_the_log() -> ‘html‘:
    contents = []
    with open(‘vsearch.log‘) as log:
        for lines in log:
            contents.append([])
            for item in lines.split(‘|‘):
                contents[-1].append(escape(item))
    titles = (‘From Data‘,‘Remote_addr‘,‘User_agent‘,‘Results‘)
    return render_template(‘viewlog.html‘,
                            the_title = ‘View Log‘,
                            the_row_titles = titles,
                            the_data = contents,)

保存后是flask重启web应用,然后进入http://127.0.0.1:5000/viewlog查看日志:

我对这个结果很满意,因为终于得到了想要的输出,并且看起来很整齐。

点击右键查看网页源代码,会看到日志的每一个数据项都放在它自己的<td>标记中,每个数据行也有自己的<tr>标记,整个表放在一个HTML的<table>中。

后面的放大来看:

大体上可以看出来一些,现在对于网页的源代码好像有一些眉目了。

回顾整个代码:

原文地址:https://www.cnblogs.com/sebastiane-root/p/9541705.html

时间: 2024-10-29 23:53:07

Python构建web应用(进阶版)->对网页HTML优化逻辑显示的相关文章

python构建web应用(入门级)

构建一个web应用 前面的学习回顾: IDLE是Python内置的IDE,用来试验和执行Python代码,可以是单语句代码段,也可以是文本编辑器中的多语句程序. 四个内置数据结构:列表.字典.集合和元组. 已经使用过的Python语句:if , elif , else , return , for , from , import . 已经知道Python提供的丰富的标准库,已经使用过的模块:datetime , random , sys , os , time , html , pprint ,

python对web服务器做压力测试并做出图形直观显示

压力测试有很多工具啊.apache的,还有jmeter, 还有loadrunner,都比较常用. 其实你自己用python写的,也足够用. 压力测试过程中要统计时间. 比如每秒的并发数,每秒的最大响应时间, 最小响应时间, 平均响应时间.最后再统一所有的请求完成后的上术参数. 将这些参数输出成CSV格式的文件. 如果不知道什么是CSV就是指将数据用引号包起来,中间用逗号分开,一系统数据放一行. 有了这个CSV文件,你用EXCEL打开来做图就可以. 如果你熟练,可以使用gnuplot这个命令行工具

NodeJs+http+fs+request+cheerio 采集,保存数据,并在网页上展示(构建web服务器)

目的: 数据采集 写入本地文件备份 构建web服务器 将文件读取到网页中进行展示 目录结构: package.json文件中的内容与上一篇一样:NodeJs+Request+Cheerio 采集数据 request :https://github.com/request/request 使得请求变得更容易,简单 cheerio:https://github.com/cheeriojs/cheerio 用来解析dom结构,类似jQuery,挺好用 app.js文件: /** * 数据采集 * 写入

[分享]《Flask Web开发:基于Python的Web应用开发实战(第2版)》中文PDF+源代码

下载:Flask Web开发第二版<Flask Web开发:基于Python的Web应用开发实战>第二版中文PDF,324页,带目录和书签,文字能够复制粘贴:配套源代码:经典书籍第二版,讲解详细,分三部分,全面介绍如何基于Python微框架Flask进行Web开发. 如图: 原文地址:http://blog.51cto.com/14086980/2320849

《FlaskWeb开发基于Python的Web应用开发实战第2版》中英PDF+源代码等4本书学习

资源链接:https://pan.baidu.com/s/1p7CyLEodCy3e1u93jTVQLg<Flask Web开发 基于Python的Web应用开发实战第2版>中英PDF+源代码以及第1版中英PDF+源代码等4本书中文版PDF,324页,带目录和书签,文字能够复制粘贴:英文版PDF,394页,带目录和书签,文字能够复制粘贴:配套源代码:经典书籍第二版,讲解详细:如图: 原文地址:http://blog.51cto.com/13371447/2322857

学习参考《Flask Web开发:基于Python的Web应用开发实战(第2版)》中文PDF+源代码

在学习python Web开发时,我们会选择使用Django.flask等框架. 在学习flask时,推荐学习看看<Flask Web开发:基于Python的Web应用开发实战(第2版)> 分三部分,全面介绍如何基于Python微框架Flask进行Web开发.第一部分是Flask简介,介绍使用Flask框架及扩展开发Web程序的必备基础知识.第二部分则给出一个实例,真正带领大家一步步开发完整的博客和社交应用Flasky,从而将前述知识融会贯通,付诸实践.第三部分介绍了发布应用之前必须考虑的事项

Python核心编程 第3版 中文版pdf

[下载地址] <Python核心编程(第3版)>是经典畅销图书<Python核心编程(第二版)>的全新升级版本,总共分为3部分.第1部分为讲解了Python的一些通用应用,包括正则表达式.网络编程.Internet客户端编程.多线程编程.GUI编程.数据库编程.Microsoft Office编程.扩展Python等内容.第2部分讲解了与Web开发相关的主题,包括Web客户端和服务器.CGI和WSGI相关的Web编程.Django Web框架.云计算.高级Web服务.第3部分则为一

Python从入门到进阶,就靠这份书单了!

自2018年3月起,在全国计算机二级考试中加入了"Python语言程序设计"科目. 从 2018 年起,浙江省信息技术教材将不会再使用晦涩难懂的 VB 语言,而是改学更简单易懂的 Python 语言.也就是说,Python 将纳入高考内容之一. Python已经进入山东省小学教材,小学生都要学Python了? 这不是天方夜谈, Python进入小学课堂是已经发生的事实, 还在纠结自己要不要学习编程吗? AlphaGo 使用的是Python 语言,python同时也是一门人工智能语言.

实战:基于Python构建运维自动化平台

导语: 今天与大家一起探讨如何基于Python构建一个可扩展的运维自动化平台,也希望能与大家一起交流,共同成长. 此次分享将通过介绍OMServer.OManager具备的功能.架构设计.模块定制.安全审计.C/S结构的实现等几个方面的内容来展开. 为什么选择Python? 默认安装且跨平台 可读性好且开发效率高 丰富的第三方库(开发框架.各类API.科学计算.GUI等) 社区活跃&众多开发者. Python在腾讯的现状,根据去年内部提交组件语言统计,除去2.3.4前端技术,Python在高级编