--********************************************************************************************************************************

--import------import requests 模块---python爬虫----------------------------------------------------------------------------

--********************************************************************************************************************************

用Pyhton自带的urllib或urllib2模块抓取网页或许有些陈词滥调了,今天我们就来玩儿些新鲜的,来看Python使用lxml模块和Requests模块抓取HTML页面的教程


--********************************************************************************************************************************

--import------import urllib 模块---数组相关----------------------------------------------------------------------------

--********************************************************************************************************************************

--方法1--urllib.urlopen(url[, data[, proxies]])    创建一个表示远程url的类文件对象,然后像本地文件一样操作这个类文件对象来获取远程数据。

url: 表示远程数据的路径,一般是网址;

data: 表示以post方式提交到url的数据(玩过web的人应该知道提交数据的两种方式:  post与get。如果你不清楚,也不必太在意,一般情况下很少用到这个参数);

proxies: 用于设置代理。

urlopen返回 一个类文件对象,它提供了如下方法:

read() , readline() , readlines() , fileno() , close() :  这些方法的使用方式与文件对象完全一样;

info():  返回一个httplib.HTTPMessage 对象,表示远程服务器返回的头信息

getcode():  返回Http状态码。如果是http请求,200表示请求成功完成;404表示网址未找到;

geturl():  返回请求的url;


import urllib

url = "http://www.baidu.com/"

#urlopen()

sock = urllib.urlopen(url)

htmlCode = sock.read()

sock.close

fp = open("e:/1.html","wb")

fp.write(htmlCode)

fp.close

#urlretrieve()

urllib.urlretrieve(url, 'e:/2.html')

--方法2--urllib.urlretrieve(url[, filename[, reporthook[, data]]])      直接将远程数据下载到本地

url: 外部/本地url

filename: 指定了保存到本地的路径(如果未指定该参数,urllib会生成一个临时文件来保存数据);

reporthook: 是一个回调函数,当连接上服务器、以及相应的数据块传输完毕的时候会触发该回调。我们可以利用这个回调函数来显示当前的下载进度。

data: 指post到服务器的数据。该方法返回一个包含两个元素的元组(filename, headers),filename表示保存到本地的路径,header表示服务器的响应头。

下面通过例子来演示一下这个方法的使用,这个例子将新浪首页的html抓取到本地,保存在D:/sina.html文件中,同时显示下载的进度。

import urllib

def callbackfunc(blocknum, blocksize, totalsize):

    '''回调函数

    @blocknum: 已经下载的数据块

    @blocksize: 数据块的大小

    @totalsize: 远程文件的大小

    '''

    percent = 100.0 * blocknum * blocksize / totalsize

    if percent > 100:

        percent = 100

    print "%.2f%%"% percent

url = 'http://www.sina.com.cn'

local = 'd:\\sina.html'

urllib.urlretrieve(url, local, callbackfunc)

--********************************************************************************************************************************

--import------import urllib2 模块---数组相关----------------------------------------------------------------------------

--********************************************************************************************************************************


--********************************************************************************************************************************

--import------import lxml 模块---数组相关----------------------------------------------------------------------------

--********************************************************************************************************************************

Web抓取

Web站点使用HTML描述,这意味着每个web页面是一个结构化的文档。有时从中 获取数据同时保持它的结构是有用的。web站点不总是以容易处理的格式, 如 csv 或者 json 提供它们的数据。

这正是web抓取出场的时机。Web抓取是使用计算机程序将web页面数据进行收集 并整理成所需格式,同时保存其结构的实践。

lxml和Requests

lxml(http://lxml.de/)是一个优美的扩展库,用来快速解析XML以及HTML文档 即使所处理的标签非常混乱。我们也将使用 Requests (http://docs.python-requests.org/en/latest/#)模块取代内建的urllib2模块,因为其速度更快而且可读性更好。你可以通过使用 pip install lxml 与 pip install requests 命令来安装这两个模块。

让我们以下面的导入开始:

?

1

2

from lxml import html

import requests

下一步我们将使用 requests.get 来从web页面中取得我们的数据, 通过使用 html 模块解析它,并将结果保存到 tree 中。

?

1

2

page = requests.get('http://econpy.pythonanywhere.com/ex/001.html')

tree = html.fromstring(page.text)

tree 现在包含了整个HTML文件到一个优雅的树结构中,我们可以使用两种 方法访问:  XPath以及CSS选择器。在这个例子中,我们将选择前者。

XPath是一种在结构化文档(如HTML或XML)中定位信息的方式。一个关于XPath的 不错的介绍参见 W3Schools 。

有很多工具可以获取元素的XPath,如Firefox的FireBug或者Chrome的Inspector。 如果你使用Chrome,你可以右键元素,选择 ‘Inspect element',高亮这段代码, 再次右击,并选择 ‘Copy XPath'。

在进行一次快速分析后,我们看到在页面中的数据保存在两个元素中,一个是title是 ‘buyer-name' 的div,另一个class是 ‘item-price' 的span:

?

1

2

<div title="buyer-name">Carson Busses</div>

<span class="item-price">$29.95</span>

知道这个后,我们可以创建正确的XPath查询并且使用lxml的 xpath 函数, 像下面这样:

?

1

2

3

4

#这将创建buyers的列表:

buyers = tree.xpath('//div[@title="buyer-name"]/text()')

#这将创建prices的列表:

prices = tree.xpath('//span[@class="item-price"]/text()')

让我们看看我们得到了什么:

print 'Buyers: ', buyers

print 'Prices: ', prices

Buyers: ['Carson Busses', 'Earl E. Byrd', 'Patty Cakes',

'Derri Anne Connecticut', 'Moe Dess', 'Leda Doggslife', 'Dan Druff',

'Al Fresco', 'Ido Hoe', 'Howie Kisses', 'Len Lease', 'Phil Meup',

'Ira Pent', 'Ben D. Rules', 'Ave Sectomy', 'Gary Shattire',

'Bobbi Soks', 'Sheila Takya', 'Rose Tattoo', 'Moe Tell']


Prices: ['$29.95', '$8.37', '$15.26', '$19.25', '$19.25',

'$13.99', '$31.57', '$8.49', '$14.47', '$15.86', '$11.11',

'$15.98', '$16.27', '$7.50', '$50.85', '$14.26', '$5.68',

'$15.00', '$114.07', '$10.09']

恭喜!我们已经成功地通过lxml与Request,从一个web页面中抓取了所有我们想要的 数据。我们将它们以列表的形式存在内存中。现在我们可以对它做各种很酷的事情了:   我们可以使用Python分析它,或者我们可以将之保存为一个文件并向世界分享。

我们可以考虑一些更酷的想法:  修改这个脚本来遍历该例数据集中剩余的页面,或者 使用多线程重写这个应用从而提升它的速度。

--********************************************************************************************************************************

--import------import lxml 模块---数组相关----------------------------------------------------------------------------

--********************************************************************************************************************************

本文实例讲述了python中requests模块的使用方法。分享给大家供大家参考。具体分析如下:

在HTTP相关处理中使用python是不必要的麻烦,这包括urllib2模块以巨大的复杂性代价获取综合性的功能。相比于urllib2,Kenneth Reitz的Requests模块更能简约的支持完整的简单用例。

简单的

想象下我们试图使用get方法从http://example.test/获取资源并且查看返回代码,content-type头信息,还有response的主体内容。这件事无论使用urllib2 或者Requests都是很容易实现的。

urllib2

>>> import urllib2

>>> url = 'http://example.test/'

>>> response = urllib2.urlopen(url)

>>> response.getcode()

200

>>> response.headers.getheader('content-type')

'text/html; charset=utf-8'

>>> response.read()

'Hello, world!'

Requests

>>> import requests

>>> url = 'http://example.test/'

>>> response = requests.get(url)

>>> response.status_code

200

>>> response.headers['content-type']

'text/html; charset=utf-8'

>>> response.content

u'Hello, world!'

这两种方法很相似,相对于urllib2调用方法读取response中的属性信息,Requests则是使用属性名来获取对应的属性值。

两者还有两个细微但是很重要的差别:

1 Requests 自动的把返回信息有Unicode解码

2 Requests 自动保存了返回内容,所以你可以读取多次,而不像urllib2.urlopen()那样返回的只是一个类似文件类型只能读取一次的对象。

第二点是在python交互式环境下操作代码很令人讨厌的事情

一个复杂一点的

现在让我们尝试下复杂点得使用GET方法获取http://foo.test/secret的资源,这次需要基本的http验证。使用上面的代码作为模板,好像我们只要把urllib2.urlopen() 到requests.get()之间的代码换成可以发送username,password的请求就行了

这是urllib2的方法:

>>> import urllib2

>>> url = 'http://example.test/secret'

>>> password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()

>>> password_manager.add_password(None, url, 'dan', 'h0tdish')

>>> auth_handler = urllib2.HTTPBasicAuthHandler(password_manager)

>>> opener = urllib2.build_opener(auth_handler)

>>> urllib2.install_opener(opener)

>>> response = urllib2.urlopen(url)

>>> response.getcode()

200

>>> response.read()

'Welcome to the secret page!'

一个简单的方法中实例化了2个类,然后组建了第三个类,最后还要装载到全局的urllib2模块中,最后才调用了urlopen,那么那两个复杂的类是什么的

迷惑了吗,  这里所有urllib2的文档 http://docs.python.org/release/2.7/library/urllib2.html

那Requests是怎么样解决同样的问题的呢?

Requests

>>> import requests

>>> url = 'http://example.test/secret'

>>> response = requests.get(url,auth=('dan','h0tdish'))

>>> response.status_code

200

>>> response.content

u'Welcome to the secret page!'

只是在调用方法的时候增加了一个auth关键字函数

我敢打赌你不用查文档也能记住。

错误处理 Error Handling

Requests对错误的处理也是很非常方面。如果你使用了不正确的用户名和密码,urllib2会引发一个urllib2.URLError错误,然而Requests会像你期望的那样返回一个正常的response对象。只需查看response.ok的布尔值便可以知道是否登陆成功。

>>> response = requests.get(url,auth=('dan','wrongPass'))

>>> response.ok

False

其他的一些特性:

* Requests对于HEAD, POST, PUT, PATCH, 和 DELETE方法的api同样简单

* 它可以处理多部分上传,同样支持自动转码

* 文档更好

* 还有更多

Requests 是很好的,下次需要使用HTTP时候可以试试。

希望本文所述对大家的Python程序设计有所帮助。

--python3使用requests模块爬取页面内容的实战演练

本篇文章主要介绍了python3使用requests模块爬取页面内容的实战演练,具有一定的参考价值,有兴趣的可以了解一下

1.安装pip

我的个人桌面系统用的linuxmint,系统默认没有安装pip,考虑到后面安装requests模块使用pip,所以我这里第一步先安装pip。

$ sudo apt install python-pip

安装成功,查看PIP版本:

$ pip -V

2.安装requests模块

这里我是通过pip方式进行安装:

$ pip install requests

运行import requests,如果没提示错误,那说明已经安装成功了!

检验是否安装成功

3.安装beautifulsoup4

Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航,查找、修改文档的方式。Beautiful Soup会帮你节省数小时甚至数天的工作时间。

$ sudo apt-get install python3-bs4

注:  这里我使用的是python3的安装方式,如果你用的是python2,可以使用下面命令安装。

$ sudo pip install beautifulsoup4

4.requests模块浅析

1)发送请求

首先当然是要导入 Requests 模块:

>>> import requests

然后,获取目标抓取网页。这里我以下为例:

>>> r = requests.get('http://www.jb51.net/article/124421.htm')

这里返回一个名为 r 的响应对象。我们可以从这个对象中获取所有我们想要的信息。这里的get是http的响应方法,所以举一反三你也可以将其替换为put、delete、post、head。

2)传递URL参数

有时我们想为 URL 的查询字符串传递某种数据。如果你是手工构建 URL,那么数据会以键/值对的形式置于 URL 中,跟在一个问号的后面。例如, cnblogs.com/get?key=val。 Requests 允许你使用 params 关键字参数,以一个字符串字典来提供这些参数。

举例来说,当我们google搜索“python爬虫”关键词时,newwindow(新窗口打开)、q及oq(搜索关键词)等参数可以手工组成URL ,那么你可以使用如下代码:

>>> payload = {'newwindow': '1', 'q': 'python爬虫', 'oq': 'python爬虫'}

>>> r = requests.get("https://www.google.com/search", params=payload)

3)响应内容

通过r.text或r.content来获取页面响应内容。

>>> import requests

>>> r = requests.get('https://github.com/timeline.json')

>>> r.text

Requests 会自动解码来自服务器的内容。大多数 unicode 字符集都能被无缝地解码。这里补充一点r.text和r.content二者的区别,简单说:

resp.text返回的是Unicode型的数据;

resp.content返回的是bytes型也就是二进制的数据;

所以如果你想取文本,可以通过r.text,如果想取图片,文件,则可以通过r.content。

4)获取网页编码

>>> r = requests.get('http://www.cnblogs.com/')

>>> r.encoding

'utf-8'

5)获取响应状态码

我们可以检测响应状态码:

>>> r = requests.get('http://www.cnblogs.com/')

>>> r.status_code

200

5.案例演示

最近公司刚引入了一款OA系统,这里我以其官方说明文档页面为例,并且只抓取页面中文章标题和内容等有用信息。

演示环境

操作系统:  linuxmint

python版本:  python 3.5.2

使用模块:  requests、beautifulsoup4

代码如下:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

_author_ = 'GavinHsueh'

import requests

import bs4

#要抓取的目标页码地址

url = 'http://www.ranzhi.org/book/ranzhi/about-ranzhi-4.html'

#抓取页码内容,返回响应对象

response = requests.get(url)

#查看响应状态码

status_code = response.status_code

#使用BeautifulSoup解析代码,并锁定页码指定标签内容

content = bs4.BeautifulSoup(response.content.decode("utf-8"), "lxml")

element = content.find_all(id='book')

print(status_code)

print(element)

程序运行返回爬去结果:

抓取成功

关于爬去结果乱码问题

其实起初我是直接用的系统默认自带的python2操作的,但在抓取返回内容的编码乱码问题上折腾了老半天,google了多种解决方案都无效。在被python2“整疯“之后,只好老老实实用python3了。对于python2的爬取页面内容乱码问题,欢迎各位前辈们分享经验,以帮助我等后生少走弯路。

后记

python的爬虫相关模块有很多,除了requests模块,再如urllib和pycurl以及tornado等。相比而言,我个人觉得requests模块是相对简单易上手的了。通过文本,大家可以迅速学会使用python的requests模块爬取页码内容。本人能力有限,如果文章有任何错误欢迎不吝赐教,其次如果大家有任何关于python爬去页面内容的疑难杂问,也欢迎和大家一起交流讨论。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

Python使用lxml模块和Requests模块抓取HTML页面的教程

用Pyhton自带的urllib或urllib2模块抓取网页或许有些陈词滥调了,今天我们就来玩儿些新鲜的,来看Python使用lxml模块和Requests模块抓取HTML页面的教程:

Web抓取

Web站点使用HTML描述,这意味着每个web页面是一个结构化的文档。有时从中 获取数据同时保持它的结构是有用的。web站点不总是以容易处理的格式, 如 csv 或者 json 提供它们的数据。

这正是web抓取出场的时机。Web抓取是使用计算机程序将web页面数据进行收集 并整理成所需格式,同时保存其结构的实践。

lxml和Requests

lxml(http://lxml.de/)是一个优美的扩展库,用来快速解析XML以及HTML文档 即使所处理的标签非常混乱。我们也将使用 Requests (http://docs.python-requests.org/en/latest/#)模块取代内建的urllib2模块,因为其速度更快而且可读性更好。你可以通过使用 pip install lxml 与 pip install requests 命令来安装这两个模块。

让我们以下面的导入开始:

from lxml import html

import requests

下一步我们将使用 requests.get 来从web页面中取得我们的数据, 通过使用 html 模块解析它,并将结果保存到 tree 中。

page = requests.get('http://econpy.pythonanywhere.com/ex/001.html')

tree = html.fromstring(page.text)

tree 现在包含了整个HTML文件到一个优雅的树结构中,我们可以使用两种 方法访问:  XPath以及CSS选择器。在这个例子中,我们将选择前者。

XPath是一种在结构化文档(如HTML或XML)中定位信息的方式。一个关于XPath的 不错的介绍参见 W3Schools 。

有很多工具可以获取元素的XPath,如Firefox的FireBug或者Chrome的Inspector。 如果你使用Chrome,你可以右键元素,选择 ‘Inspect element',高亮这段代码, 再次右击,并选择 ‘Copy XPath'。

在进行一次快速分析后,我们看到在页面中的数据保存在两个元素中,一个是title是 ‘buyer-name' 的div,另一个class是 ‘item-price' 的span:

<div title="buyer-name">Carson Busses</div>

<span class="item-price">$29.95</span>

知道这个后,我们可以创建正确的XPath查询并且使用lxml的 xpath 函数, 像下面这样:

#这将创建buyers的列表:

buyers = tree.xpath('//div[@title="buyer-name"]/text()')

#这将创建prices的列表:

prices = tree.xpath('//span[@class="item-price"]/text()')

让我们看看我们得到了什么:

print 'Buyers: ', buyers

print 'Prices: ', prices

Buyers: ['Carson Busses', 'Earl E. Byrd', 'Patty Cakes',

'Derri Anne Connecticut', 'Moe Dess', 'Leda Doggslife', 'Dan Druff',

'Al Fresco', 'Ido Hoe', 'Howie Kisses', 'Len Lease', 'Phil Meup',

'Ira Pent', 'Ben D. Rules', 'Ave Sectomy', 'Gary Shattire',

'Bobbi Soks', 'Sheila Takya', 'Rose Tattoo', 'Moe Tell']

Prices: ['$29.95', '$8.37', '$15.26', '$19.25', '$19.25',

'$13.99', '$31.57', '$8.49', '$14.47', '$15.86', '$11.11',

'$15.98', '$16.27', '$7.50', '$50.85', '$14.26', '$5.68',

'$15.00', '$114.07', '$10.09']

恭喜!我们已经成功地通过lxml与Request,从一个web页面中抓取了所有我们想要的 数据。我们将它们以列表的形式存在内存中。现在我们可以对它做各种很酷的事情了:   我们可以使用Python分析它,或者我们可以将之保存为一个文件并向世界分享。

我们可以考虑一些更酷的想法:  修改这个脚本来遍历该例数据集中剩余的页面,或者 使用多线程重写这个应用从而提升它的速度。

--Python 使用requests模块发送GET和POST请求的实现代码

这篇文章主要介绍了Python 使用requests模块发送GET和POST请求的实现代码,需要的朋友可以参考下

①GET

# -*- coding:utf-8 -*-

import requests

def get(url, datas=None):

  response = requests.get(url, params=datas)

  json = response.json()

  return json

注:  参数datas为json格式

②POST

# -*- coding:utf-8 -*-

import requests

def post(url, datas=None):

  response = requests.post(url, data=datas)

  json = response.json()

  return json

注:  参数datas为json格式

--********************************************************************************************************************************

--import------import cgi 模块---CGI编程-------------Common Gateway Interface---------------------------------------------------------------

--********************************************************************************************************************************

什么是CGI

CGI 目前由NCSA维护,NCSA定义CGI如下:

CGI,通用网关接口,它是一段程序,运行在服务器上如:  HTTP服务器,提供同客户端HTML页面的接口。

网页浏览

为了更好的了解CGI是如何工作的,我们可以从在网页上点击一个链接或URL的流程:

1、使用你的浏览器访问URL并连接到HTTP web 服务器。

2、Web服务器接收到请求信息后会解析URL,并查找访问的文件在服务器上是否存在,如果存在返回文件的内容,否则返回错误信息。

3、浏览器从服务器上接收信息,并显示接收的文件或者错误信息。

CGI程序可以是Python脚本,PERL脚本,SHELL脚本,C或者C++程序等。

CGI架构图

cgiarch

Web服务器支持及配置

在你进行CGI编程前,确保您的Web服务器支持CGI及已经配置了CGI的处理程序。

Apache 支持CGI 配置:

设置好CGI目录:

ScriptAlias /cgi-bin/ /var/www/cgi-bin/

所有的HTTP服务器执行CGI程序都保存在一个预先配置的目录。这个目录被称为CGI目录,并按照惯例,它被命名为/var/www/cgi-bin目录。

CGI文件的扩展名为.cgi,python也可以使用.py扩展名。

默认情况下,Linux服务器配置运行的cgi-bin目录中为/var/www。

如果你想指定其他运行 CGI 脚本的目录,可以修改 httpd.conf 配置文件,如下所示:

<Directory "/var/www/cgi-bin">

   AllowOverride None

   Options +ExecCGI

   Order allow,deny

   Allow from all

</Directory>

在 AddHandler 中添加 .py 后缀,这样我们就可以访问 .py 结尾的 python 脚本文件:

AddHandler cgi-script .cgi .pl .py

第一个CGI程序

我们使用Python创建第一个CGI程序,文件名为hello.py,文件位于/var/www/cgi-bin目录中,内容如下:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

print "Content-type:text/html"

print                               # 空行,告诉服务器结束头部

print '<html>'

print '<head>'

print '<meta charset="utf-8">'

print '<title>Hello Word - 我的第一个 CGI 程序!</title>'

print '</head>'

print '<body>'

print '<h2>Hello Word! 我是来自菜鸟教程的第一CGI程序</h2>'

print '</body>'

print '</html>'

文件保存后修改 hello.py,修改文件权限为 755:

chmod 755 hello.py

以上程序在浏览器访问显示结果如下:

这个的hello.py脚本是一个简单的Python脚本,脚本第一行的输出内容"Content-type:text/html"发送到浏览器并告知浏览器显示的内容类型为"text/html"。

用 print 输出一个空行用于告诉服务器结束头部信息。

HTTP头部

hello.py文件内容中的" Content-type:text/html"即为HTTP头部的一部分,它会发送给浏览器告诉浏览器文件的内容类型。

HTTP头部的格式如下:

HTTP 字段名: 字段内容

例如:

Content-type: text/html

以下表格介绍了CGI程序中HTTP头部经常使用的信息:

描述

Content-type:请求的与实体对应的MIME信息。例如: Content-type:text/html

Expires: Date响应过期的日期和时间

Location: URL用来重定向接收方到非请求URL的位置来完成请求或标识新的资源

Last-modified: Date请求资源的最后修改时间

Content-length: N请求的内容长度

Set-Cookie: String设置Http Cookie

CGI环境变量

所有的CGI程序都接收以下的环境变量,这些变量在CGI程序中发挥了重要的作用:

CONTENT_TYPE这个环境变量的值指示所传递来的信息的MIME类型。目前,环境变量CONTENT_TYPE一般都是:  application/x-www-form-urlencoded,他表示数据来自于HTML表单。

CONTENT_LENGTH如果服务器与CGI程序信息的传递方式是POST,这个环境变量即使从标准输入STDIN中可以读到的有效数据的字节数。这个环境变量在读取所输入的数据时必须使用。

HTTP_COOKIE客户机内的 COOKIE 内容。

HTTP_USER_AGENT提供包含了版本数或其他专有数据的客户浏览器信息。

PATH_INFO这个环境变量的值表示紧接在CGI程序名之后的其他路径信息。它常常作为CGI程序的参数出现。

QUERY_STRING如果服务器与CGI程序信息的传递方式是GET,这个环境变量的值即使所传递的信息。这个信息经跟在CGI程序名的后面,两者中间用一个问号'?'分隔。

REMOTE_ADDR这个环境变量的值是发送请求的客户机的IP地址,例如上面的192.168.1.67。这个值总是存在的。而且它是Web客户机需要提供给Web服务器的唯一标识,可以在CGI程序中用它来区分不同的Web客户机。

REMOTE_HOST这个环境变量的值包含发送CGI请求的客户机的主机名。如果不支持你想查询,则无需定义此环境变量。

REQUEST_METHOD提供脚本被调用的方法。对于使用 HTTP/1.0 协议的脚本,仅 GET 和 POST 有意义。

SCRIPT_FILENAMECGI脚本的完整路径

SCRIPT_NAMECGI脚本的的名称

SERVER_NAME这是你的 WEB 服务器的主机名、别名或IP地址。

SERVER_SOFTWARE这个环境变量的值包含了调用CGI程序的HTTP服务器的名称和版本号。例如,上面的值为Apache/2.2.14(Unix)

以下是一个简单的CGI脚本输出CGI的环境变量:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

# filename:test.py

import os

print "Content-type: text/html"

print

print "<meta charset=\"utf-8\">"

print "<b>环境变量</b><br>";

print "<ul>"

for key in os.environ.keys():

    print "<li><span style='color:green'>%30s </span> : %s </li>" % (key,os.environ[key])

print "</ul>"

将以上点保存为 test.py ,并修改文件权限为 755,执行结果如下:

GET和POST方法

浏览器客户端通过两种方法向服务器传递信息,这两种方法就是 GET 方法和 POST 方法。

使用GET方法传输数据

GET方法发送编码后的用户信息到服务端,数据信息包含在请求页面的URL上,以"?"号分割, 如下所示:

http://www.test.com/cgi-bin/hello.py?key1=value1&key2=value2 有关 GET 请求的其他一些注释:

GET 请求可被缓存

GET 请求保留在浏览器历史记录中

GET 请求可被收藏为书签

GET 请求不应在处理敏感数据时使用

GET 请求有长度限制

GET 请求只应当用于取回数据

简单的url实例:  GET方法

以下是一个简单的URL,使用GET方法向hello_get.py程序发送两个参数:

/cgi-bin/test.py?name=菜鸟教程&url=http://www.runoob.com

以下为hello_get.py文件的代码:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

# filename:  test.py

# CGI处理模块

import cgi, cgitb

# 创建 FieldStorage 的实例化

form = cgi.FieldStorage()

# 获取数据

site_name = form.getvalue('name')

site_url  = form.getvalue('url')

print "Content-type:text/html"

print

print "<html>"

print "<head>"

print "<meta charset=\"utf-8\">"

print "<title>菜鸟教程 CGI 测试实例</title>"

print "</head>"

print "<body>"

print "<h2>%s官网:  %s</h2>" % (site_name, site_url)

print "</body>"

print "</html>"

文件保存后修改 hello_get.py,修改文件权限为 755:

chmod 755 hello_get.py

浏览器请求输出结果:

简单的表单实例:  GET方法

以下是一个通过HTML的表单使用GET方法向服务器发送两个数据,提交的服务器脚本同样是hello_get.py文件,hello_get.html 代码如下:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

</head>

<body>

<form action="/cgi-bin/hello_get.py" method="get">

站点名称: <input type="text" name="name">  <br />

站点 URL: <input type="text" name="url" />

<input type="submit" value="提交" />

</form>

</body>

</html>

默认情况下 cgi-bin 目录只能存放脚本文件,我们将 hello_get.html 存储在 test 目录下,修改文件权限为 755:

chmod 755 hello_get.html

Gif 演示如下所示:

使用POST方法传递数据

使用POST方法向服务器传递数据是更安全可靠的,像一些敏感信息如用户密码等需要使用POST传输数据。

以下同样是hello_get.py ,它也可以处理浏览器提交的POST表单数据:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

# CGI处理模块

import cgi, cgitb

# 创建 FieldStorage 的实例化

form = cgi.FieldStorage()

# 获取数据

site_name = form.getvalue('name')

site_url  = form.getvalue('url')

print "Content-type:text/html"

print

print "<html>"

print "<head>"

print "<meta charset=\"utf-8\">"

print "<title>菜鸟教程 CGI 测试实例</title>"

print "</head>"

print "<body>"

print "<h2>%s官网:  %s</h2>" % (site_name, site_url)

print "</body>"

print "</html>"

以下为表单通过POST方法(method="post")向服务器脚本 hello_get.py 提交数据:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

</head>

<body>

<form action="/cgi-bin/hello_get.py" method="post">

站点名称: <input type="text" name="name">  <br />

站点 URL: <input type="text" name="url" />

<input type="submit" value="提交" />

</form>

</body>

</html>

Gif 演示如下所示:

通过CGI程序传递checkbox数据

checkbox用于提交一个或者多个选项数据,HTML代码如下:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

</head>

<body>

<form action="/cgi-bin/checkbox.py" method="POST" target="_blank">

<input type="checkbox" name="runoob" value="on" /> 菜鸟教程

<input type="checkbox" name="google" value="on" /> Google

<input type="submit" value="选择站点" />

</form>

</body>

</html>

以下为 checkbox.py 文件的代码:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

# 引入 CGI 处理模块

import cgi, cgitb

# 创建 FieldStorage的实例

form = cgi.FieldStorage()

# 接收字段数据

if form.getvalue('google'):

   google_flag = "是"

else:

   google_flag = "否"

if form.getvalue('runoob'):

   runoob_flag = "是"

else:

   runoob_flag = "否"

print "Content-type:text/html"

print

print "<html>"

print "<head>"

print "<meta charset=\"utf-8\">"

print "<title>菜鸟教程 CGI 测试实例</title>"

print "</head>"

print "<body>"

print "<h2> 菜鸟教程是否选择了 : %s</h2>" % runoob_flag

print "<h2> Google 是否选择了 : %s</h2>" % google_flag

print "</body>"

print "</html>"

修改 checkbox.py 权限:

chmod 755 checkbox.py

浏览器访问 Gif 演示图:

通过CGI程序传递Radio数据

Radio 只向服务器传递一个数据,HTML代码如下:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

</head>

<body>

<form action="/cgi-bin/radiobutton.py" method="post" target="_blank">

<input type="radio" name="site" value="runoob" /> 菜鸟教程

<input type="radio" name="site" value="google" /> Google

<input type="submit" value="提交" />

</form>

</body>

</html>

radiobutton.py 脚本代码如下:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

# 引入 CGI 处理模块

import cgi, cgitb

# 创建 FieldStorage的实例

form = cgi.FieldStorage()

# 接收字段数据

if form.getvalue('site'):

   site = form.getvalue('site')

else:

   site = "提交数据为空"

print "Content-type:text/html"

print

print "<html>"

print "<head>"

print "<meta charset=\"utf-8\">"

print "<title>菜鸟教程 CGI 测试实例</title>"

print "</head>"

print "<body>"

print "<h2> 选中的网站是 %s</h2>" % site

print "</body>"

print "</html>"

修改 radiobutton.py 权限:

chmod 755 radiobutton.py

浏览器访问 Gif 演示图:

通过CGI程序传递 Textarea 数据

Textarea 向服务器传递多行数据,HTML代码如下:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

</head>

<body>

<form action="/cgi-bin/textarea.py" method="post" target="_blank">

<textarea name="textcontent" cols="40" rows="4">

在这里输入内容...

</textarea>

<input type="submit" value="提交" />

</form>

</body>

</html>

textarea.py 脚本代码如下:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

# 引入 CGI 处理模块

import cgi, cgitb

# 创建 FieldStorage的实例

form = cgi.FieldStorage()

# 接收字段数据

if form.getvalue('textcontent'):

   text_content = form.getvalue('textcontent')

else:

   text_content = "没有内容"

print "Content-type:text/html"

print

print "<html>"

print "<head>";

print "<meta charset=\"utf-8\">"

print "<title>菜鸟教程 CGI 测试实例</title>"

print "</head>"

print "<body>"

print "<h2> 输入的内容是:  %s</h2>" % text_content

print "</body>"

print "</html>"

修改 textarea.py 权限:

chmod 755 textarea.py

浏览器访问 Gif 演示图:

通过CGI程序传递下拉数据。

HTML 下拉框代码如下:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

</head>

<body>

<form action="/cgi-bin/dropdown.py" method="post" target="_blank">

<select name="dropdown">

<option value="runoob" selected>菜鸟教程</option>

<option value="google">Google</option>

</select>

<input type="submit" value="提交"/>

</form>

</body>

</html>

dropdown.py 脚本代码如下所示:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

# 引入 CGI 处理模块

import cgi, cgitb

# 创建 FieldStorage的实例

form = cgi.FieldStorage()

# 接收字段数据

if form.getvalue('dropdown'):

   dropdown_value = form.getvalue('dropdown')

else:

   dropdown_value = "没有内容"

print "Content-type:text/html"

print

print "<html>"

print "<head>"

print "<meta charset=\"utf-8\">"

print "<title>菜鸟教程 CGI 测试实例</title>"

print "</head>"

print "<body>"

print "<h2> 选中的选项是:  %s</h2>" % dropdown_value

print "</body>"

print "</html>"

修改 dropdown.py 权限:

chmod 755 dropdown.py

浏览器访问 Gif 演示图:

CGI中使用Cookie

在 http 协议一个很大的缺点就是不对用户身份的进行判断,这样给编程人员带来很大的不便, 而 cookie 功能的出现弥补了这个不足。

cookie 就是在客户访问脚本的同时,通过客户的浏览器,在客户硬盘上写入纪录数据 ,当下次客户访问脚本时取回数据信息,从而达到身份判别的功能,cookie 常用在身份校验中。

 

--cookie的语法

http cookie的发送是通过http头部来实现的,他早于文件的传递,头部set-cookie的语法如下:

Set-cookie:name=name;expires=date;path=path;domain=domain;secure

name=name: 需要设置cookie的值(name不能使用";"和","号),有多个name值时用 ";" 分隔,例如:  name1=name1;name2=name2;name3=name3。

expires=date: cookie的有效期限,格式:   expires="Wdy,DD-Mon-YYYY HH:MM:SS"

path=path: 设置cookie支持的路径,如果path是一个路径,则cookie对这个目录下的所有文件及子目录生效,例如:   path="/cgi-bin/",如果path是一个文件,则cookie指对这个文件生效,例如:  path="/cgi-bin/cookie.cgi"。

domain=domain: 对cookie生效的域名,例如:  domain="www.runoob.com"

secure: 如果给出此标志,表示cookie只能通过SSL协议的https服务器来传递。

cookie的接收是通过设置环境变量HTTP_COOKIE来实现的,CGI程序可以通过检索该变量获取cookie信息。

--Cookie设置

Cookie的设置非常简单,cookie会在http头部单独发送。以下实例在cookie中设置了name 和 expires:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

#

print 'Content-Type: text/html'

print 'Set-Cookie: name="菜鸟教程";expires=Wed, 28 Aug 2016 18:30:00 GMT'

print

print """

<html>

    <head>

        <meta charset="utf-8">

        <title>菜鸟教程(runoob.com)</title>

    </head>

    <body>

        <h1>Cookie set OK!</h1>

    </body>

</html>

"""

将以上代码保存到 cookie_set.py,并修改 cookie_set.py 权限:

chmod 755 cookie_set.py

以上实例使用了 Set-Cookie 头信息来设置Cookie信息,可选项中设置了Cookie的其他属性,如过期时间Expires,域名Domain,路径Path。这些信息设置在 "Content-type:text/html"之前。

--检索Cookie信息----Cookie信息检索页非常简单,Cookie信息存储在CGI的环境变量HTTP_COOKIE中,

存储格式:    key1=value1;key2=value2;key3=value3....

以下是一个简单的CGI检索cookie信息的程序:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

# 导入模块

import os

import Cookie

print "Content-type: text/html"

print

print """

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

</head>

<body>

<h1>读取cookie信息</h1>

"""

if 'HTTP_COOKIE' in os.environ:

    cookie_string=os.environ.get('HTTP_COOKIE')

    c=Cookie.SimpleCookie()

    c.load(cookie_string)

    try:

        data=c['name'].value

        print "cookie data: "+data+"<br>"

    except KeyError:

        print "cookie 没有设置或者已过去<br>"

print """

</body>

</html>

"""

将以上代码保存到 cookie_get.py,并修改 cookie_get.py 权限:

chmod 755 cookie_get.py

以上 cookie 设置颜色 Gif 如下所示:

文件上传实例

HTML设置上传文件的表单需要设置 enctype 属性为 multipart/form-data,代码如下所示:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

</head>

<body>

 <form enctype="multipart/form-data"

                     action="/cgi-bin/save_file.py" method="post">

   <p>选中文件: <input type="file" name="filename" /></p>

   <p><input type="submit" value="上传" /></p>

   </form>

</body>

</html>

save_file.py脚本文件代码如下:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

import cgi, os

import cgitb; cgitb.enable()

form = cgi.FieldStorage()

# 获取文件名

fileitem = form['filename']

# 检测文件是否上传

if fileitem.filename:

   # 设置文件路径

   fn = os.path.basename(fileitem.filename)

   open('/tmp/' + fn, 'wb').write(fileitem.file.read())

   message = '文件 "' + fn + '" 上传成功'

else:

   message = '文件没有上传'

print """\

Content-Type: text/html\n

<html>

<head>

<meta charset="utf-8">

<title>菜鸟教程(runoob.com)</title>

</head>

<body>

   <p>%s</p>

</body>

</html>

""" % (message,)

将以上代码保存到 save_file.py,并修改 save_file.py 权限:

chmod 755 save_file.py

以上 cookie 设置颜色 Gif 如下所示:

如果你使用的系统是Unix/Linux,你必须替换文件分隔符,在window下只需要使用open()语句即可:

fn = os.path.basename(fileitem.filename.replace("\\", "/" ))

文件下载对话框

我们先在当前目录下创建 foo.txt 文件,用于程序的下载。

文件下载通过设置HTTP头信息来实现,功能代码如下:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

# HTTP 头部

print "Content-Disposition: attachment; filename=\"foo.txt\"";

print

# 打开文件

fo = open("foo.txt", "rb")

str = fo.read();

print str

# 关闭文件

fo.close()