系列教程导航

  1. Python 基础教程
  2. 在 SublimeEditor 中配置 Python 环境
  3. Python 代码中添加注释
  4. Python 中的变量的使用
  5. Python 中的数据类型
  6. Python 中的关键字
  7. Python 字符串操作
  8. Python 中的 list 操作
  9. Python 中的 Tuple 操作
  10. Python max()和 min()– 在列表或数组中查找最大值和最小值
  11. Python 找到最大的 N 个(前 N 个)或最小的 N 个项目
  12. Python 读写 CSV 文件
  13. Python 中使用 httplib2 – HTTP GET 和 POST 示例
  14. Python 将 tuple 开箱为变量或参数
  15. Python 开箱 Tuple – 太多值无法解压
  16. Python multidict 示例– 将单个键映射到字典中的多个值
  17. Python OrderedDict – 有序字典
  18. Python 字典交集– 比较两个字典
  19. Python 优先级队列示例

简介

本文介绍如何使用 Python 的 httplib2 模块。超文本传输协议(HTTP)是用于分布式、协作、超媒体信息系统的应用协议,也是万维网数据通信的基础。

Python 的 httplib2 模块提供了通过 HTTP 访问 Web 资源的方法。它支持多种功能,例如 HTTP 和 HTTPS 协议、身份验证、缓存、重定向和压缩。

环境准备

我们在本地主机上运行 Nginx Web 服务器,部分示例将连接本地 Nginx 服务器上运行的 PHP 脚本。

$ service nginx status

* nginx is running

目录

检查 httplib2 库版本

第一个程序用于打印库的版本、版权信息和文档字符串。

#!/usr/bin/python3

import httplib2

print(httplib2.__version__)

print(httplib2.__copyright__)

print(httplib2.__doc__)

httplib2.__version__ 提供库的版本,httplib2.__copyright__ 提供版权信息,httplib2.__doc__ 提供文档字符串。

$ ./version.py

0.8

Copyright 2006, Joe Gregorio

httplib2

A caching http interface that supports ETags and gzip

to conserve bandwidth.

Requires Python 3.0 or later

Changelog:

2009-05-28, Pilgrim: ported to Python 3

2007-08-18, Rick: Modified so it's able to use a socks proxy if needed.

以下是示例的输出结果。

使用 httplib2 读取网页

在下面的示例中,我们展示了如何从名为 www.something.com 的网站获取 HTML 内容。

#!/usr/bin/python3

import httplib2

http = httplib2.Http()

content = http.request("http://www.something.com")[1]

print(content.decode())

使用 httplib2.Http() 创建一个 HTTP 客户端。使用 request() 方法创建一个新的 HTTP 请求,默认情况下它是一个 GET 请求。返回值是响应对象和内容的元组。

$ ./get_content.py

<html><head><title>Something.</title></head>

<body>Something.</body>

</html>

剥离 HTML 标签

以下程序获取一个小型网页,并剥离其 HTML 标签。

#!/usr/bin/python3

import httplib2

import re

http = httplib2.Http()

content = http.request("http://www.something.com")[1]

stripped = re.sub('<[^<]+?>', '', content.decode())

print(stripped)

这里使用一个简单的正则表达式来剥离 HTML 标记。请注意,我们只是剥离了数据,并没有对其进行清理(这是两件不同的事)。

$ ./strip_tags.py

Something.

Something.

该脚本将打印网页的标题和内容。

检查响应状态

响应对象包含 status 属性,提供响应状态代码。

#!/usr/bin/python3

import httplib2

http = httplib2.Http()

resp = http.request("http://www.something.com")[0]

print(resp.status)

resp = http.request("http://www.something.com/news/")[0]

print(resp.status)

我们使用 request() 方法执行两个 HTTP 请求,并检查返回的状态。

$ ./get_status.py

200

404

200 是成功 HTTP 请求的标准响应,而 404 则表明找不到所请求的资源。

发送 HTTP HEAD 请求

HTTP HEAD 方法用于检索文档标题。标头由字段组成,包括日期、服务器、内容类型或上次修改时间等。

#!/usr/bin/python3

import httplib2

http = httplib2.Http()

resp = http.request("http://www.something.com", "HEAD")[0]

print("Server: " + resp['server'])

print("Last modified: " + resp['last-modified'])

print("Content type: " + resp['content-type'])

print("Content length: " + resp['content-length'])

该示例打印服务器、上次修改时间、内容类型和 www.something.com 网页的内容长度。

$ ./do_head.py

Server: Apache/2.4.12 (FreeBSD) OpenSSL/1.0.1l-freebsd mod_fastcgi/mod_fastcgi-SNAP-0910052141

Last modified: Mon, 25 Oct 1999 15:36:02 GMT

Content type: text/html

Content length: 72

从输出中我们可以看到,该网页是由 FreeBSD 托管的 Apache Web 服务器交付的。文档的最后修改时间为 1999 年。网页是 HTML 文档,其长度为 72 个字节。

发送 HTTP GET 请求

HTTP GET 方法请求指定资源的表示形式。对于此示例,我们还将使用 greet.php 脚本:

<?php

echo "Hello " . htmlspecialchars($_GET['name']);

?>

/usr/share/nginx/html/ 目录内,我们存有此 greet.php 文件。该脚本返回 name 变量的值,该值是从客户端检索的。

htmlspecialchars() 函数将特殊字符转换为 HTML 实体;例如 & 转换为 &amp;

#!/usr/bin/python3

import httplib2

http = httplib2.Http()

content = http.request("http://localhost/greet.php?name=Peter",

method="GET")[1]

print(content.decode())

该脚本将带有值的变量发送到服务器上的 PHP 脚本,变量直接在 URL 中指定。

$ ./mget.py

Hello Peter

以下是示例的输出。

$ tail -1 /var/log/nginx/access.log

127.0.0.1 - - [21/Aug/2016:17:32:31 +0200] "GET /greet.php?name=Peter HTTP/1.1" 200 42 "-"

"Python-httplib2/0.8 (gzip)"

我们检查了 Nginx 访问日志。

发送 HTTP POST 请求

POST 请求方法请求 Web 服务器接受并存储请求消息正文中包含的数据。上载文件或提交完整的 Web 表单时经常使用它。

<?php

echo "Hello " . htmlspecialchars($_POST['name']);

?>

在本地 Web 服务器上,我们存有此 target.php 文件。它只是将 POST 的值打印回客户端。

#!/usr/bin/python3

import httplib2

import urllib

http = httplib2.Http()

body = {'name': 'Peter'}

content = http.request("http://localhost/target.php",

method="POST",

headers={'Content-type': 'application/x-www-form-urlencoded'},

body=urllib.parse.urlencode(body) )[1]

print(content.decode())

脚本发送 name 键带有 Peter 值的请求。数据使用 urllib.parse.urlencode() 方法进行编码,并在请求的正文中发送。

$ ./mpost.py

Hello Peter

以下是 mpost.py 脚本的输出。

$ tail -1 /var/log/nginx/access.log

127.0.0.1 - - [23/Aug/2016:12:21:07 +0200] "POST /target.php HTTP/1.1"

200 37 "-" "Python-httplib2/0.8 (gzip)"

使用 POST 方法时,值不会在请求 URL 中发送。

发送用户代理信息

在本节中,我们指定用户代理(User Agent)的名称。

<?php

echo $_SERVER['HTTP_USER_AGENT'];

?>

在 Nginx 文档根目录下,我们有 agent.php 文件。它返回用户代理的名称。

#!/usr/bin/python3

import httplib2

http = httplib2.Http()

content = http.request("http://localhost/agent.php", method="GET",

headers={'user-agent': 'Python script'})[1]

print(content.decode())

该脚本向 agent.php 脚本创建一个简单的 GET 请求。在 headers 字典中,我们指定用户代理。PHP 脚本将读取此内容,并将其返回给客户端。

$ ./user_agent.py

Python script

服务器使用我们随请求发送的代理名称进行了响应。

将用户名/密码添加到请求

客户端的 add_credentials() 方法设置用于领域的名称和密码。安全领域(Realm)是一种用于保护 Web 应用程序资源的机制。

$ sudo apt-get install apache2-utils

$ sudo htpasswd -c /etc/nginx/.htpasswd user7

New password:

Re-type new password:

Adding password for user user7

我们使用 htpasswd 工具创建用于基本 HTTP 身份验证的用户名和密码。

location /secure {

auth_basic "Restricted Area";

auth_basic_user_file /etc/nginx/.htpasswd;

}

在 Nginx /etc/nginx/sites-available/default 配置文件中,我们创建一个安全页面。领域的名称为"Restricted Area"。

<!DOCTYPE html>

<html lang="en">

<head>

<title>Secure page</title>

</head>

<body>

<p>

This is a secure page.

</p>

</body>

</html>

/usr/share/nginx/html/secure 目录中,我们存有上面的 HTML 文件。

#!/usr/bin/python3

import httplib2

user = 'user7'

passwd = '7user'

http = httplib2.Http()

http.add_credentials(user, passwd)

content = http.request("http://localhost/secure/")[1]

print(content.decode())

该脚本连接到安全网页;它提供访问该页面所需的用户名和密码。

$ ./credentials.py

<!DOCTYPE html>

<html lang="en">

<head>

<title>Secure page</title>

</head>

<body>

<p>

This is a secure page.

</p>

</body>

</html>

使用正确的凭据,脚本将返回受保护的页面。

在本教程中,我们探索了 Python httplib2 模块。

说明httplib2 是一个较老的 HTTP 客户端库。在现代 Python 开发中,通常更推荐使用 requests 库,因为它提供了更简洁的 API 和更好的维护支持。本文示例基于 httplib2 0.8 版本及 Python 3 环境。