设为首页 收藏本站
查看: 1022|回复: 0

[经验分享] [PYTHON] 核心编程笔记(20.Web编程)

[复制链接]

尚未签到

发表于 2018-8-11 08:57:23 | 显示全部楼层 |阅读模式
  20.1 介绍
  20.1.1 Web应用:客户端/服务器计算
  20.1.2 因特网
  20.2 使用Python进行Web应用:创建一个简单的Web客户端
  20.2.1 统一资源定位符
  20.2.2 urlparse模块
  urlparse(urlstr, defProtSch=None, allowFrag=None)
  urlunparse(urltup)
  urlparse.urljoin()
  urljoin(baseurl, newurl,allowFrag=None)
  20.2.3 urllib模块
  urllib.urlopen()
  urlopen(urlstr, postQueryData=None)
  urllib.urlretrieve()
  urlretrieve(urlstr, localfile=None, downloadStatusHook=None)
  urllib.quote() and urllib,quote_plus()
  urllib函数描述
  urlopen(urlstr,postQurey-Data=None)
  20.2.4 urllib2 模块
  我们可以建立一个基础认证处理器(urllib2.HTTPBasicAuthHandler),同时在基
  本URL或域上注册一个登陆密码,这就意味着我们在Web站点上定义了个安全区域,
  一旦完成这些,你可以安装URL打开器,通过这个处理器打开所有的URL
  另一个可选办法就是当浏览器提示的时候,输入用户名和密码,这样就发送了一个
  带有适当用户请求的认证头
  # vi urlopenAuth.py(问题)
  -----------------------------------------
  #!/usr/bin/env python
  import urllib2
  LOGIN = 'wesley'
  PASSWD = "you'llNeverGuess"
  URL = 'http://localhost'
  def handler_version(url):
  from urlparse import urlparse as up
  hdlr = urllib2.HTTPBasicAuthHandler()
  hdlr.add_password('Archives', up(url)[1], LOGIN, PASSWD)
  opener = urllib2.build_opener(hdlr)
  urllib2.install_opener(opener)
  return url
  def request_version(url):
  from base64 import encodestring
  req = urllib2.Request(url)
  b64str = encodestring('%s:%s' % (LOGIN, PASSWD))[:-1]
  req.add_header("Authorization", "Basic %s" % b64str)
  return req
  for funcType in ('handler', 'request'):
  print '*** Using %s:' % funcType.upper()
  url = eval('%s_version')(URL)
  f = urllib2.urlopen(url)
  print f.readline()
  f.close()
  -----------------------------------------
  20.3 高级Web客户端
  Web浏览器是基本的Web客户端,主要用来在Web上查询或者下载文件
  高级Web客户端的一个例子就是网络爬虫,这些程序可以基于不同目的在因特网上
  探索和下载页面:
  1.为Google和Yahho这类大型搜索引擎建立索引
  2.脱机浏览一将文档下载到本地,重新设定超链接,为本地浏览器创建镜像
  3.下载并保存历史记录或框架
  4.Web页的缓存,节省再次访问Web站点的下载时间
  20.4 CGI:帮助Web服务器处理客户端数据
  20.4.1 CGI介绍
  CGI代表了在一个web服务器和能够处理用户表单,生成并返回动态HTML页的应用
  程序间的交互
  20.4.2 CGI应用程序
  当一个CGI脚本开始执行时,它需要检索用户-支持表单,但这些数据必须要从web
  客户端才可以获得,而不是从服务器或者硬盘上获得,所有的交互都将发生在Web
  客户端,Web服务器端和CGI应用程序间
  20.4.2 cgi模块
  20.5 建立CGI应用程序
  20.5.1 建立Web服务器
  为了可以用Python进行CGI开发,首先需要安装一个Web服务器,将其配置成可以处
  理Python CGI请求的模式,然后让你的Web服务器访问CGI脚本
  1.可以下载安装apache及其Python CGI插件模块
  2.利用Python自带的web服务器
  # python -m CGIHTTPServer
  ---------------------------------
  Serving HTTP on 0.0.0.0 port 8000 ...
  ---------------------------------
  20.5.2 建立表单页
  20.5.3 生成结果页
  1.登陆一个非root账户,在当前目录下建立一个端口号为8000的web服务器
  # cd ~
  # pwd
  ---------------------
  /home/python
  ---------------------
  # mkdir web
  # cd web
  # python -m CGIHTTPServer
  2.在启动这个服务器的目录下建立一个cgi-bin,并将Python CGI脚本放到该目录
  # mkdir cgi-bin
  # cd cgi-bin
  # vi friends1.py
  -------------------------
  #!/usr/bin/env python
  import cgi
  reshtml = '''Content-Type: text/html\n
  <HTML><HEAD><TITLE>
  Friends CGI Demo (dynamic screen)
  </TITLE></HEAD>
  <BODY><H3>Friends list for: <I>%s</I></H3>
  Your name is: <B>%s</B><P>
  You have <B>%s</B> friends.
  </BODY></HTML>'''
  form = cgi.FieldStorage()
  who = form['person'].value
  howmany = form['howmany'].value
  print reshtml % (who, who, howmany)
  -------------------------
  3.创建web表单:
  这个HTML文件展示给用户一个空文档,含有用户名,和一系列可供用户选择的单选
  按钮
  # cd ..
  # pwd
  --------------------
  /home/python/web
  --------------------
  # vi friends.htm
  ------------------------------------
  <HTML>
  <HEAD>
  <TITLE>CGI Demo(static screen)</TITLE>
  </HEAD>
  <BODY><H3>Friends list for: <I>NEW USER</I></H3>
  <FORM ACTION='cgi-bin/friends1.py'>
  <B>Enter your Name:</B>

  <INPUT TYPE='text' NAME=person VALUE='NEW USER'>  <P><B>How many friends do you have?</B></P>
  <INPUT TYPE='radio' NAME=howmany VALUE='0' CHECKED> 0
  <INPUT TYPE='radio' NAME=howmany VALUE='10'> 10
  <INPUT TYPE='radio' NAME=howmany VALUE='25'> 25
  <INPUT TYPE='radio' NAME=howmany VALUE='50'> 50
  <INPUT TYPE='radio' NAME=howmany VALUE='100'> 100
  <P><INPUT TYPE=submit></P>
  </FORM>
  </BODY>
  </HTML>
  ------------------------------------
  表单的变量是FieldStorage的实例,包含person和howmany 字段值,我们把值存入
  Python的who和howmany变量,变量reshtml包含需要返回的HTML文本正文,还有一
  些动态填好的字段,这些数据都是从表单中读入的
  4.浏览器访问页面
  http://localhost:8000/friends.htm
  20.5.4 生成表单和结果页面
  将friends.html和friends1.py合并成friends2.py,得到的脚本可以同时显示表
  单和动态生成的HTML结果页面,同时可以巧妙的知道应该输出哪个页面
  # vi friends2.py
  ---------------------------------
  #!/usr/bin/env python
  '''
  $Id: friends2.py,v 1.1 2000/12/31 01:32:45 wesc Exp $
  CGI demo
  '''
  import cgi
  header = 'Content-Type: text/html\n\n'
  formhtml = '''<HTML><HEAD><TITLE>Friends CGI Demo</TITLE></HEAD>
  <BODY><H3>Friends list for: <I>NEW USER</I></H3>
  <FORM ACTION="/cgi-bin/friends2.py">
  <B>Enter your Name:</B>
  <INPUT TYPE=hidden NAME=action VALUE=edit>

  <INPUT TYPE=text NAME=person VALUE="">  <P><B>How many friends do you have?</B>
  %s
  <P><INPUT TYPE=submit></FORM></BODY></HTML>'''
  friendradio = '<INPUT TYPE=radio NAME=howmany VALUE="%s" %s> %s\n'
  def showForm():
  friends = ''
  for i in [0, 10, 25, 50, 100]:
  checked = ''
  if i == 0:
  checked = 'CHECKED'
  friends = friends + friendradio % (str(i), checked, str(i))
  print header + formhtml % (friends)
  reshtml = '''<HTML><HEAD><TITLE>Friends CGI Demo</TITLE></HEAD>
  <BODY><H3>Friends list for: <I>%s</I></H3>
  Your name is: <B>%s</B><P>
  You have <B>%s</B> friends.
  </BODY></HTML>'''
  def doResults(who, howmany):
  # substitute in real name and number of friends and return
  print header + reshtml % (who, who, howmany)
  # process() does all the work
  def process():

  # initialize Data>  form = cgi.FieldStorage()
  # get user name
  if form.has_key('person'):
  who = form['person'].value
  else:
  who = 'NEW USER'
  # get name and number of friends
  if form.has_key('howmany'):
  howmany = form['howmany'].value
  else:
  howmany = 0
  # if editing, show results
  if form.has_key('action'):
  doResults(who, howmany)
  # otherwise, show form
  else:
  showForm()
  # invoke if called directly
  if __name__ == '__main__':
  process()
  ---------------------------------
  20.5.5 全面交互的web站点
  我们最后一个例子将会完成这个循环
  用户在表单页中输入他/她的信息,然后我们处理这些数据,并输出一个结果页面
  现在我们将会在结果页面上加个链接允许返回到表单页面,但是我们返回的是含
  有用户输入信息的页面而不是一个空白页面,我们页面上加上了一些错误处理程
  序,来展示它是如何实现的
  例,通过加上返回输入信息的表单页面连接,我们实现了整个循环,并加上一些错
  误验证,在用户没有选择任何单选按钮时,通知用户
  # vi friends3.py
  --------------------------------
  #!/usr/bin/env python
  '''
  $Id: friends3.py,v 1.1 2000/12/31 01:32:45 wesc Exp $
  Friends CGI demo
  '''
  import cgi
  from urllib import quote_plus
  from string import capwords
  #from sys import stderr
  #s = stderr.write
  header = 'Content-Type: text/html\n\n'
  url = 'http://192.168.102.88:8000/cgi-bin/friends3.py'
  errhtml = '''<HTML><HEAD><TITLE>Friends CGI Demo</TITLE></HEAD>
  <BODY><H3>ERROR</H3>
  <B>%s</B><P>
  <FORM><INPUT TYPE=button VALUE=Back></FORM>
  </BODY></HTML>'''
  # showError() --> None
  def showError(error_str):
  'showError() -- display error message'
  print header + errhtml % (error_str)
  friendradio = '<INPUT TYPE=radio NAME=howmany VALUE="%s" %s> %s\n'
  formhtml = '''<HTML><HEAD><TITLE>Friends CGI Demo</TITLE></HEAD>
  <BODY><H3>Friends list for: <I>%s</I></H3>
  <FORM ACTION="%s">
  <B>Your Name:</B>
  <INPUT TYPE=hidden NAME=action VALUE=edit>

  <INPUT TYPE=text NAME=person VALUE="%s">  <P><B>How many friends do you have?</B>
  %s
  <P><INPUT TYPE=submit></FORM></body></html>'''
  # showForm() --> None
  def showForm(who, howmany):
  'showForm() -- presents blank or data-filled form for new input'
  friends = ''
  for i in [0, 10, 25, 50, 100]:
  checked = ''
  if str(i) == howmany:
  checked = 'CHECKED'
  friends = friends + friendradio % (str(i), checked, str(i))
  print header + formhtml % (who, url, who, friends)
  reshtml = '''<HTML><HEAD><TITLE>Friends CGI Demo</TITLE></HEAD>
  <BODY><H3>Friends list for: <I>%s</I></H3>
  Your name is: <B>%s</B><P>
  You have <B>%s</B> friends.
  <P>Click <a href="%s">here</a> to edit your data again.
  </BODY></HTML>'''
  # doResults() --> None
  def doResults(who, howmany):
  'doResults() -- displays results with given form data'
  # substitute in real name and number of friends and return
  newurl = url + '?action=reedit&person=%s&howmany=%s' %
  (quote_plus(who), howmany)
  print header + reshtml % (who, who, howmany, newurl)
  # process() --> None
  def process():
  'process() does all the work:  grabs user data and determines
  routine to call'
  error = ''

  # initialize Data>  form = cgi.FieldStorage()
  #s('name: '+str(form.name)+'\n')
  #s('keys: '+str(form.keys())+'\n')
  #for i in form.keys():
  #s('item: '+str(form.name)+' has a value of '+str(form
  .value)+' and is a ' + form.__class__.__name__ + '\n')
  # get user name
  if form.has_key('person'):
  who = capwords(form['person'].value)
  else:
  who = 'NEW USER'
  # get name and number of friends
  if form.has_key('howmany'):
  howmany = form['howmany'].value
  else:
  if form.has_key('action') and form['action'].value == 'edit':
  error = 'Please select the number of friends you have.'
  else:
  howmany = 0
  # no errors, either display form or present results
  if not error:
  # if editing the first time, show results
  if form.has_key('action') and form['action'].value !=
  'reedit':
  doResults(who, howmany)
  # otherwise, show form
  else:
  showForm(who, howmany)
  # send error message back if error situation
  else:
  showError(error)
  # invoke if called directly
  if __name__ == '__main__':
  process()
  --------------------------------
  20.6 在CGI中使用Unide编码
  例,简单Unicode CGI示例(uniCGI.py)
  这个脚本输出到你web浏览器端的是Unicode字符串
  # vi uniCGI.py
  --------------------------------
  #!/usr/bin/env python
  CODEC = 'UTF-8'
  UNICODE_HELLO = u'''
  Hello!
  \u00A1Hola!
  \u4F60\u597D!
  \u3053\u3093\u306B\u3061\u306F!
  '''
  print 'Content-Type: text/html; charset=%s\r' % CODEC
  print '\r'
  print '<HTML><HEAD><TITLE>Unicode CGI Demo</TITLE></HEAD>'
  print '<BODY>'
  print UNICODE_HELLO.encode(CODEC)
  print '</BODY></HTML>'
  --------------------------------
  20.7 高级CGI
  20.7.1 Mulitipart 表单提交和文件上传
  20.7.2 多值字段
  20.7.3 cookie
  20.7.4 使用高级CGI
  例,这个脚本有一个处理所有事情的主函数,AdvCGI,它有方法显示表单,错误或结
  果页面,同事也可以从客户端(Web浏览器)读写cookie
  # vi advcgi.py(问题)
  ----------------------------
  #!/usr/bin/env python
  from cgi import FieldStorage
  from os import environ
  from cStringIO import StringIO
  from urllib import quote, unquote
  from string import capwords, strip, split, join
  class AdvCGI:
  header = 'Content-Type: text/html\n\n'
  url = '/py/advcgi.py'
  formhtml = '''<HTML><HEAD><TITLE>
  Advanced CGI Demo</TITLE></HEAD>
  <BODY><H2>Advanced CGI Demo Form</H2>
  <FORM METHOD=post ACTION="%s" ENCTYPE="multipart/form-data">
  <H3>My Cookie Setting</H3>
  <LI> <CODE><B>CPPuser = %s</B></CODE>
  <H3>Enter cookie value<BR>
  <INPUT NAME=cookie value="%s"> (<I>optional</I>)</H3>
  <H3>Enter your name<BR>
  <INPUT NAME=person VALUE="%s"> (<I>required</I>)</H3>
  <H3>What languages can you program in?
  (<I>at least one required</I>)</H3>
  %s
  <H3>Enter file to upload</H3>

  <INPUT TYPE=file NAME=upfile VALUE="%s">  <P><INPUT TYPE=submit>
  </FORM></BODY></HTML>'''
  langSet = ('Python', 'PERL', 'Java', 'C++', 'PHP',
  'C', 'JavaScript')
  langItem = \
  '<INPUT TYPE=checkbox NAME=lang VALUE="%s"%s> %s\n'
  def getCPPCookies(self):                # reads cookies from
  client
  if environ.has_key('HTTP_COOKIE'):
  for eachCookie in map(strip, \
  split(environ['HTTP_COOKIE'], ';')):
  if len(eachCookie) > 6 and \
  eachCookie[:3] == 'CPP':
  tag = eachCookie[3:7]
  try:
  self.cookies[tag] = \
  eval(unquote(eachCookie[8:]))
  except (NameError, SyntaxError):
  self.cookies[tag] = \
  unquote(eachCookie[8:])
  else:
  self.cookies['info'] = self.cookies['user'] = ''
  if self.cookies['info'] != '':
  self.who, langStr, self.fn = \
  split(self.cookies['info'], ':')
  self.langs = split(langStr, ',')
  else:
  self.who = self.fn = ''
  self.langs = ['Python']
  def showForm(self):                        # show fill-out form
  self.getCPPCookies()
  langStr = ''
  for eachLang in AdvCGI.langSet:
  if eachLang in self.langs:
  langStr = langStr + AdvCGI.langItem % \
  (eachLang, ' CHECKED', eachLang)
  else:
  langStr = langStr + AdvCGI.langItem % \
  (eachLang, '', eachLang)
  if not self.cookies.has_key('user') or \
  self.cookies['user'] == '':
  cookieStatus = '<I>(cookie has not been set yet)</I>'
  userCook = ''
  else:
  userCook = cookieStatus = self.cookies['user']
  print AdvCGI.header + AdvCGI.formhtml % (AdvCGI.url,
  cookieStatus, userCook, self.who, langStr, self.fn)
  errhtml = '''<HTML><HEAD><TITLE>
  Advanced CGI Demo</TITLE></HEAD>
  <BODY><H3>ERROR</H3>
  <B>%s</B><P>
  <FORM><INPUT TYPE=button VALUE=Back
  ></FORM>
  </BODY></HTML>'''
  def showError(self):
  print AdvCGI.header + AdvCGI.errhtml % (self.error)
  reshtml = '''<HTML><HEAD><TITLE>
  Advanced CGI Demo</TITLE></HEAD>
  <BODY><H2>Your Uploaded Data</H2>
  <H3>Your cookie value is: <B>%s</B></H3>
  <H3>Your name is: <B>%s</B></H3>
  <H3>You can program in the following languages:</H3>
  <UL>%s</UL>
  <H3>Your uploaded file...<BR>
  Name: <I>%s</I><BR>
  Contents:</H3>
  <PRE>%s</PRE>
  Click <A HREF="%s"><B>here</B></A> to return to form.
  </BODY></HTML>'''
  def setCPPCookies(self):
  for eachCookie in self.cookies.keys():
  print 'Set-Cookie: CPP%s=%s; path=/' % \
  (eachCookie, quote(self.cookies[eachCookie]))
  def doResults(self):
  MAXBYTES = 1024
  langlist = ''
  for eachLang in self.langs:
  langlist = langlist + '<LI>%s<BR>' % eachLang
  filedata = ''
  while len(filedata) < MAXBYTES:        # read file chunks
  data = self.fp.readline()
  if data == '': break
  filedata = filedata + data
  else:                                # truncate if too long
  filedata = filedata + \

  '... <B><I>(file truncated due to>  self.fp.close()
  if filedata == '':
  filedata = \
  '<B><I>(file upload error or file not given)</I></B>'
  filename = self.fn
  if not self.cookies.has_key('user') or \
  self.cookies['user'] == '':
  cookieStatus = '<I>(cookie has not been set yet)</I>'
  userCook = ''
  else:
  userCook = cookieStatus = self.cookies['user']
  self.cookies['info'] = join([self.who, \
  join(self.langs, ','), filename], ':')
  self.setCPPCookies()
  print AdvCGI.header + AdvCGI.reshtml % \
  (cookieStatus, self.who, langlist,
  filename, filedata, AdvCGI.url)
  def go(self):                # determine which page to return
  self.cookies = {}
  self.error = ''
  form = FieldStorage()
  if form.keys() == []:
  self.showForm()
  return
  if form.has_key('person'):
  self.who = capwords(strip(form['person'].value))
  if self.who == '':
  self.error = 'Your name is required. (blank)'
  else:
  self.error = 'Your name is required. (missing)'
  if form.has_key('cookie'):
  self.cookies['user'] = unquote(strip( \
  form['cookie'].value))
  else:
  self.cookies['user'] = ''
  self.langs = []
  if form.has_key('lang'):
  langdata = form['lang']
  if type(langdata) == type([]):
  for eachLang in langdata:
  self.langs.append(eachLang.value)
  else:
  self.langs.append(langdata.value)
  else:
  self.error = 'At least one language required.'
  if form.has_key('upfile'):
  upfile = form["upfile"]
  self.fn = upfile.filename or ''
  if upfile.file:
  self.fp = upfile.file
  else:
  self.fp = StringIO('(no data)')
  else:
  self.fp = StringIO('(no file)')
  self.fn = ''
  if not self.error:
  self.doResults()
  else:
  self.showError()
  if __name__ == '__main__':
  page = AdvCGI()
  page.go()
  ----------------------------
  20.8 Web(HTTP)服务器
  20.8.1 用Python建立Web服务器
  例,这个简单的Web服务器可以读取GET请求,获取Web页面并将其返回给客户端,它
  通过使用BaseHTTPServer的BaseHTTPRequestHandler处理器执行do_GET()方法来
  处理GET请求
  # vi myhttpd.py
  ----------------------------------
  #!/usr/bin/env python
  from os import curdir, sep
  from BaseHTTPServer import \
  BaseHTTPRequestHandler, HTTPServer
  class MyHandler(BaseHTTPRequestHandler):
  def do_GET(self):
  try:
  f = open(curdir + sep + self.path)
  self.send_response(200)
  self.send_header('Content-type',
  'text/html')
  self.end_headers()
  self.wfile.write(f.read())
  f.close()
  except IOError:
  self.send_error(404,
  'File Not Found: %s' % self.path)
  def main():
  try:
  server = HTTPServer(('', 80), MyHandler)
  print 'Welcome to the machine...'
  print 'Press ^C once or twice to quit'
  server.serve_forever()
  except KeyboardInterrupt:
  print '^C received, shutting down server'
  server.socket.close()
  if __name__ == '__main__':
  main()
  ----------------------------------
  20.9 相关模块
  ........

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-549928-1-1.html 上篇帖子: python实战系列之ip地址排序问题(二) 下篇帖子: 升级 python 2.6.6 到 2.7.14 版本(pip工具安装)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表