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

本篇是承载上一篇web应用(入门级)的始末往下顺延的,阅读后将会询问HTML逻辑显示优化,如下图所示,从繁杂的日志文件到一个俨然的列表突显。

图片 1

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

6仓储和管制数据

在下面的始末前面需要通晓存储和管理数据的学识。

关于web应用,应该记录每个web请求的多少。这样便于分析这一个题目:

已经响应了多少个请求?最常用的假名列表是怎样?请求来自哪个IP地址?哪个浏览器用的最多?……

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

 图片 2

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应用的数码开展仓储记录下来。

回溯从前的顺序内容:

图片 3

在下边添加一个函数

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中开展调用,当然在调用此前需要定义函数,所以调整地方后的次序如下:

 图片 4

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

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

 图片 5

经过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看到:

图片 6

那么些类似只是浏览器接受和呈现最终的结果,并从未最起先查找的内容,检查网页的源代码,间接浏览器中右键

图片 7

这多少个情节和刚刚的并不曾太大差异,依旧尚未看到搜索的始末,web拒绝出示用户搜索的多寡,因为HTML中<Request>是一个不合法的符号,浏览器会将它忽略。

转义数据

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

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

图片 8

在第一行调用投入escape然后在前面的return后采用函数:escape(contents)

新的测试结果:

图片 9

留神到刚刚是黄色的字变成了绿色字,,然则那一个数字并无法看出来怎么着。

转移代码:

图片 10

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

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

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

密切看看现在的始末,有意义了呢?

图片 11

这不啻有些乱,但是细心看会发现有一对大家查找到的值。

图片 12

明天能够看来各类请求都有恢宏的涉嫌方法和属性,记录所有的属性是没有意义的。其中有四个对于日记记录很关键:

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

下边对代码举行更加的调整。

记录特定的web请求属性

 图片 13

分别出口这多少个情节,end=‘|’表示把默认的换行符替换为|,这样一个请求的数据就是单排内容。

这是新的日记文件的内容:能够看出数据都在一行而且整齐了累累

图片 14

上文中的连续三个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会意识少了累累

图片 15

可以找到里面有追寻的字符串也有结果,看来已经有意义了。可是怎么着进一步专业这些情节呢?

从原本数据到可读的出口

下面是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可以将列表转换成字符串。

下来在>>>中展开测试:

图片 16

join后边的‘|’意思是应用|将每个字符串连接起来。

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

图片 17

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

 

修改代码:

利用文件打开的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)

有局部地点需要解释:

图片 18

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

 

封存代码然后开展测试:

图片 19

现今的输出变成了一个嵌套列表,而不再是一个字符串列表。现在大家选择一个统筹的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 %}结束。

图片 20

可以见到,第一个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查看日志:

图片 21

自家对这一个结果很惬意,因为毕竟得到了想要的输出,并且看起来很整齐。

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

图片 22

 

末尾的推广来看:

图片 23

大概上得以看出来一些,现在对此网页的源代码好像有一对模样了。

回首整整代码:

图片 24

图片 25

相关文章