Python3----第十五章 Python和Web

#!usr/bin/env python  
# -*- coding:utf-8 _*-
""" 
@author:AIVision 
@file: lecture15.py 
@time: 2023/09/27 
"""

# 第十五章 Python和Web
# 本章讨论Python Web编程的一些方面。Web编程涉及的范围极广,为激发你的学习兴趣,这
# 里挑选了其中三个重要的主题:屏幕抓取、CGI和mod_python。

# 15.1 屏幕抓取
# 屏幕抓取是通过程序下载网页并从中提取信息的过程。这种技术很有用,在网页中有你要在
# 程序中使用的信息时,就可使用它。当然,如果网页是动态的,即随时间而变化,这就更有用了。
# 如果网页不是动态的,你可手工下载一次并提取其中的信息。(当然,最理想的情况是,可通过
# Web服务来获取这些信息,这将在本章后面讨论。)
# 从概念上说,这种技术非常简单:下载数据并对其进行分析。例如,你可使用urllib来获取
# 网页的HTML代码,再使用正则表达式(参见第10章)或其他技术从中提取信息。例如,假设你
# 要从Python Job Board(http://python.org/jobs)提取招聘单位的名称和网站。通过查看该网页的源
# 代码,你发现可在类似于下面的链接中找到名称和URL:
# <a href="/jobs/1970/">Python Engineer</a>
# 代码清单15-1所示的示例程序使用urllib和re来提取所需的信息。

# 代码清单15-1 简单的屏幕抓取程序
from urllib.request import urlopen
import re
p = re.compile('<a href="(/jobs/\\d+)/">(.*?)</a>')
text = urlopen('http://python.org/jobs').read().decode()
for url, name in p.findall(text):
    print('{} ({})'.format(name, url))

# 15.1.1 Tidy 和 XHTML 解析
# Python标准库为解析HTML和XML等结构化格式提供了强大的支持(参见“Python库参考手
# 册”中的Structured Markup Processing Tools部分)。XML和XML解析将在第22章更深入地讨论,
# 这里只介绍处理XHTML所需的工具。XHTML是HTML 5规范描述的两种具体语法之一,也是一
# 种XML格式。这里介绍的大部分内容也适用于HTML。
# 如果每个网页包含的XHTML都正确而有效,解析工作将非常简单。问题是较老的HTML方
# 言不那么严谨,虽然有人指责这些不严谨的方言,但有些人对这些指责置若罔闻。原因可能在于
# 大多数Web浏览器都非常宽容,即便面对的是最混乱、最无意义的HTML,也会尽最大努力将其
# 渲染出来。这为网页制作者提供了方便,可能让他们感到满意,却让屏幕抓取工作变得难得多。
# 标准库提供的通用的HTML解析方法是基于事件的:你编写事件处理程序,供解析程序处理
# 数据时调用。标准库模块html.parser让你能够以这种方式对极不严谨的HTML进行解析,但要基
# 于文档结构来提取数据(如第二个二级标题后面的第一项),在存在标签缺失的情况下恐怕就只
# 能靠猜了。如果你愿意,当然可以这样做,但还有另一种方式——使用Tidy。

# 1. Tidy是什么
# Tidy是用于对格式不正确且不严谨的HTML进行修复的工具。它非常聪明,能够修复很多常
# 见的错误,从而完成大量你不愿意做的工作。它还提供了极大的配置空间,让你能够开/关各种
# 校正。

# 2. 获取Tidy
# 有多个用于Python的Tidy库包装器,至于哪个最新并非固定不变的。可像下面这样使用pip
# 来找出可供使用的包装器:
# $ pip search tidy
# 一个不错的选择是PyTidyLib,可像下面这样安装它:
# $ pip install pytidylib

# 3. 为何使用XHTML
# XHTML和旧式HTML的主要区别在于,XHTML非常严格,要求显式地结束所有的元素(至
# 少就我们当前的目标而言如此)。因此,在HTML中,可通过(使用标签<p>)开始另一个段落来
# 结束当前段落,但在XHTML中,必须先(使用标签</p>)显式地结束当前段落。这让XHTML
# 解析起来容易得多,因为你能清楚地知道何时进入或离开各种元素。XHTML的另一个优点是,
# 它是一种XML方言,可使用各种出色的工具(如XPath)来处理,但本章不会利用这一点。有关
# XML的详细信息,请参阅第22章。有关如何使用XPath的详细信息,请参阅http://www.w3schools.
# com/xml/xml:xpath.asp。
# 要对Tidy生成的格式良好的XHTML进行解析,一种非常简单的方式是使用标准库模块
# html.parser中的HTMLParser类。

# 4. 使用HTMLParser
# 使用HTMLParser意味着继承它,并重写各种事件处理方法,如handle_starttag和handle_data。
# 表15-1概述了相关的方法以及解析器在什么时候自动调用它们。

# 表15-1 HTMLParser中的回调方法
# 回调方法                                      何时被调用
# handle_starttag(tag, attrs)           遇到开始标签时调用。attrs是一个由形如(name, value)的元组组成的序列
# handle_startendtag(tag, attrs)        遇到空标签时调用。默认分别处理开始标签和结束标签
# handle_endtag(tag)                    遇到结束标签时调用
# handle_data(data)                     遇到文本数据时调用
# handle_charref(ref)                   遇到形如&#ref;的字符引用时调用
# handle_entityref(name)                遇到形如&name;的实体引用时调用
# handle_comment(data)                  遇到注释时;只对注释内容调用
# handle_decl(decl)                     遇到形如<!...>的声明时调用
# handle_pi(data)                       用于处理指令
# unknown_decl(data)                    遇到未知声明时调用

# 15.2 使用 CGI 创建动态网页
# 本章的第一部分讨论了客户端技术,下面将注意力转向服务器端。本节讨论基本的Web编程
# 技术:通用网关接口(CGI)。CGI是一种标准机制,Web服务器可通过它将(通常是通过Web表
# 达提供的)查询交给专用程序(如你编写的Python程序),并以网页的方式显示查询结果。这是
# 一种创建Web应用的简单方式,让你无需编写专用的应用程序服务器。有关Python CGI编程的详
# 细信息,请参阅Python网站的Web编程主题指南(http://wiki.python.org/moin/WebProgramming)。
# Python CGI编程的关键工具是模块cgi,另一个对开发CGI脚本很有帮助的模块是cgitb,将
# 在15.2.6节详细介绍。
# 要让CGI脚本能够通过Web进行访问(和运行),必须将其放在Web服务器能够访问的地方、
# 添加!#行并设置合适的文件权限。接下来依次介绍这三个步骤。

# 15.2.1 第一步:准备 Web 服务器
# 这里假设你能够访问Web服务器。换而言之,你能够将内容发布到Web。通常,要将内容发
# 布到Web,只需将网页、图像等放入特定的目录(在UNIX中通常为public_html)即可。如果你不
# 知道如何将内容发布到Web,请咨询Internet服务提供商(ISP)或系统管理员。

# 15.2.2 第二步:添加!#行
# 将脚本放到正确的位置(还可能给它指定特定的文件扩展名)后,必须在其开头添加一个!#
# 行。第1章说过,通过添加!#行,无需显式地执行Python解释器就能执行脚本。通常,这只是提
# 供了便利,但对CGI脚本来说却至关重要,因为如果没有!#行,Web服务器将不知道如何执行脚
# 本。(Web服务器只知道脚本可能是使用Perl、Ruby等其他编程语言编写的。)一般而言,只需在
# 脚本开头添加如下行即可:
# #!/usr/bin/env python
# 请注意,它必须是第一行(之前没有空行)。如果这样做不管用,就得确定Python可执行文
# 件的准确位置,并在!#行中使用完整的目录,如下所示:
# #!/usr/bin/python
# 如果同时安装了Python 2和Python 3,可能需要将python替换为python3(前面的env解决方案
# 亦如此)。如果这样做也不管用,可能存在你看不到的错误,具体地说是!#行以\r\n而不是\n结
# 尾,把Web服务器搞糊涂了。请务必将脚本保存为UNIX风格的纯文本文件。
# 在Windows中,可使用Python可执行文件的完整路径,如下所示:
# #!C:\Python36\python.exe

# 15.2.3 第三步:设置文件权限
# 需要做的最后一件事情是设置合适的文件权限(至少当Web服务器运行在UNIX或Linux系统
# 中时如此)。必须确保谁都可以读取和执行你的脚本文件(否则Web服务器将无法运行它),同时
# 确保只有你才能写入(这样其他任何人都不能修改你的脚本)。

# 15.2.4 CGI 安全风险
# 使用CGI程序存在一些安全风险。如果你允许CGI脚本对服务器中的文件执行写入操作,那
# 么这可能被人利用来破坏数据——除非编写脚本时非常小心。同样,如果直接将用户提供的数据
# 作为Python代码(如使用exec或eval)或shell命令(如使用os.system或模块subprocess)执行,
# 就可能执行恶意的命令,进而面临极大的风险。即便在SQL查询中使用用户提供的字符串也很危
# 险,除非你预先仔细审查这些字符串。SQL注入是一种常见的攻击系统的方式。

# 15.2.5 简单的 CGI 脚本
# 最简单的CGI脚本类似于代码清单15-4。
# 代码清单15-4 简单的CGI脚本
#!/usr/bin/env python
print('Content-type: text/plain')
print()# 打印一个空行,以结束首部
print('Hello, world!')


# 15.2.6 使用 cgitb 进行调试
# 有时候,编程错误可能导致程序终止,并因未捕获的异常而显示栈跟踪。通过CGI运行程序
# 时,如果出现这种情况,可能导致Web服务器显示毫无帮助的错误消息甚至黑色网页。如果你能
# 够访问服务器日志(例如,如果你使用的是http.server),可能能够在这里找到蛛丝马迹。然而,
# 为帮助调试CGI脚本,标准库提供了一个很有用的模块,名为cgitb(用于CGI栈跟踪)。通过导
# 入这个模块并调用其中的函数enable,可显示一个很有用的网页,其中包含有关什么地方出了问
# 题的信息。代码清单15-5演示了如何使用模块cgitb

# 代码清单15-5 显示栈跟踪的CGI脚本(faulty.cgi)
#!/usr/bin/env python
import cgitb; cgitb.enable()
print('Content-type: text/html\n')
print(1/0)
print('Hello, world!')

# 15.2.7 使用模块 cgi
# 到目前为止,所有CGI脚本都只生成输出,而没有使用任何形式的输入。输入是通过HTML
# 表单(将在下一节介绍)以键值对(字段)的方式提供给CGI脚本的。在CGI脚本中,可使用模
# 块cgi中的FieldStorage类来获取这些字段。当你创建FieldStorage实例(应只创建一个)时,它
# 将从请求中取回输入变量(字段),并通过一个类似于字典的接口将它们提供给脚本。要访问
# FieldStorage中的值,可通过普通的键查找,但出于一些技术原因(与文件上传相关,这里不讨
# 论),FieldStorage的元素并不是你要的值。例如,即便你知道请求包含一个名为name的值,也不
# 能像下面这样做:
# form = cgi.FieldStorage()
# name = form['name']
# 而必须这样做:
# form = cgi.FieldStorage()
# name = form['name'].value

# 15.2.8 简单的表单
# 有了处理用户请求的工具,该来创建用户可提交的表单了。这个表单可以是独立的页面,但
# 这里将它放在脚本中。
# 要深入地了解如何编写HTML表单(或HTML),可参考介绍HTML的优秀著作(当地书店可
# 能就有不少)。另外,在网上也能找到很多有关这个主题的信息。与往常一样,发现值得模仿的
# 优秀网页后,可在浏览器中查看其源代码,方法是从菜单中选择“查看源代码”之类的选项(具
# 体是哪个选项取决于你使用的浏览器)。

# 15.3 使用 Web 框架
# 对于重要的Web应用,大多数人都不会直接为其编写CGI脚本,而是选择使用Web框架,因
# 为它会替你完成很多繁重的工作。这样的框架有很多,后面将提及其中的几个,但现在要将注意
# 力放在既简单又有用的Flask(http://flask.pocoo.org)上。使用pip很容易安装这个框架。
# $ pip install flask
# 假设你编写了一个计算幂的函数。
# def powers(n=10):
#  return ', '.join(str(2**i) for i in range(n))
# 而且想让每个人都能使用它!要使用Flask来实现这个目标,首先使用合适的名称实例化Flask
# 类,并将这个函数的URL路径告诉它。
# from flask import Flask
# app = Flask(__name__)
# @app.route('/')
# def powers(n=10):
#  return ', '.join(str(2**i) for i in range(n))
# 如果这个脚本名为powers.py,就可像下面这样让Flask运行它(这里假设是在UNIX风格的
# shell中):
# $ export FLASK_APP=powers.py
# $ flask run
# * Serving Flask app "powers"
# * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

# 最后两行是Flask的输出。如果你在浏览器中输入上面的URL,将看到函数powers返回的字符
# 串。你也可给这个函数指定更具体的路径。例如,如果使用route('/powers')而不是('/'),这个
# 函数将位于http://127.0.0.1:5000/powers。这样,你就可设置多个函数,每个函数的URL各不相同。
# 你甚至能向函数提供参数。要指定参数,可使用尖括号,例如'/powers/<n>'。这样,斜杠
# 后面的内容将作为关键字参数n的值。但这样提供的是一个字符串,而这里需要的是一个整数。
# 为执行转换,可使用route('/powers/<int:n>')。这样修改后,如果重新启动Flask,并访问URL
# http://127.0.0.1:5000/powers/3,将得到输出1, 2, 4。
# Flask还有很多其他的功能,其文档也很容易理解。如果要尝试简单的服务器端Web应用开发,
# 建议你看看这些文档。

# 其他 Web 应用框架
# 还有很多其他的Web框架,大小皆有。有的晦涩难懂,有些定期召开推广会议。表15-2列出
# 了几个流行的框架,更完整的清单请参阅Python网页(https://wiki.python.org/moin/WebFrameworks)。

# 表15-2 Python Web应用框架
# 名 称           网 站
# Django        https://djangoproject.com
# TurboGears    http://turbogears.org
# web2py        http://web2py.com
# Grok          https://pypi.python.org/pypi/grok
# Zope2         https://pypi.python.org/pypi/Zope2
# Pyramid       https://trypyramid.com

# 15.4 Web 服务:更高级的抓取
# Web服务有点像对计算机友好的网页。它们基于让程序能够通过网络交换信息的标准和协
# 议——通常其中一个程序请求信息或服务(客户端或服务请求者),而另一个程序提供信息或
# 服务(服务器或服务提供者)。确实,Web服务器很容易理解,而且看起来与前面讨论的网络编
# 程很像,不过也存在差别。
# Web服务通常运行在极高的抽象层级中,将HTTP(Web使用的协议)用作底层协议。在这个
# 协议上面,它们使用更为面向内容的协议(如XML格式)来对请求和响应进行编码。这意味着
# Web服务器可作为Web服务的平台。正如本节的标题指出的,它将Web抓取提高到另一个层级。
# 你可将Web服务看作为计算机客户(而不是人类)设计的动态网页。
# 有些Web服务标准非常复杂,但在不涉及任何复杂方面的情况下也能完成很多任务。本节将
# 简要地介绍这个主题,并提供在哪里能够找到所需工具和信息的指南。

# 15.5 小结
# 下面总结了本章介绍的主题。
#  屏幕抓取:指的是自动下载网页并从中提取信息。程序Tidy及其库版本是很有用的工具,
# 可用来修复格式糟糕的HTML,然后使用HTTML解析器进行解析。另一种抓取方式是使
# 用Beautiful Soup,即便面对混乱的输入,它也可以处理。
#  CGI:通用网关接口是一种创建动态网页的方式,这是通过让Web服务器运行、与客户端
# 程序通信并显示结果而实现的。模块cgi和cgitb可用于编写CGI脚本。CGI脚本通常是在
# HTML表单中调用的。
#  Flask:一个简单的Web框架,让你能够将代码作为Web应用发布,同时不用过多操心Web
# 部分。
#  Web应用框架:要使用Python开发复杂的大型Web应用,Web应用框架必不可少。对简单
# 的项目来说,Flask是不错的选择;但对于较大的项目,你可能应考虑使用Django或
# TurboGears。
#  Web服务:Web服务之于程序犹如网页之于用户。你可以认为,Web服务让你能够以更抽
# 象的方式进行网络编程。常用的Web服务标准包括RSS(以及与之类似的RDF和Atom)、
# XML-RPC和SOAP。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_44119674

觉得有帮助,鼓励下吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值