6.4 第三方库

标准库的内容已经非常多了,前面仅仅列举几个,但是Python给编程者的支持不仅仅在于标准库,还有不可胜数的第三方库。因此,作为一个Pythoner,即使你达到了master的水平,在做某个事情之前最好在网上搜索一下是否有标准库或者第三方库能替你完成。因为,伟大的艾萨克·牛顿爵士说过:如果我比别人看得更远,那是因为我站在巨人的肩上。

编程就更要站在巨人的肩上,标准库和第三方库以及其提供者就是巨人,我们本应当谦卑地向其学习,并应用其成果。

6.4.1 安装第三方库

安装第三方库的方法有几种,不同方法有不同的优缺点,读者可以根据自己的喜好或者实际的工作情景来选择使用。

方法一:利用源码安装

在github.com网站可以下载第三方库的源码(注意,github不是源码的唯一来源,只不过很多源码都在这个网站上,我也喜欢罢了),得到源码之后,在本地安装。

如果你下载的是一个文件包,即得到的源码格式为zip或tar.zip或tar.bz2的压缩文件,需要先解压缩,然后进入其目录(文件夹);如果你能熟练使用git命令,可以直接从github中clone源码到本地计算机上,然后再进入该目录(文件夹)。进去之后通常会看见setup.py文件。如果是Linux操作系统或者苹果计算机(我是用Ubuntu系统,特别推荐哦),就在这里运行shell,执行命令:

  1. python setup.py install

如果用的是Windows系统,需要打开命令行模式,执行上述指令即可。

如此,就能把这个第三库安装到系统里。具体位置,要视操作系统和你当初安装Python环境时设置的路径而定。默认条件下,Windows是在C:\Python2.7\Lib\site-packages,Linux在/usr/local/lib/python2.7/dist-packages(这个只是参考,不同发行版会有差别,具体请读者根据自己的操作系统找找),Mac在/Library/Python/2.7/site-packages。

这种安装的方法有时候麻烦一些,但是比较灵活,主要体现在:

  • 可以下载安装自己选定的任意版本的第三方库,比如最新版,或者更早的某个版本,所以在某些有特殊需要的时候,常常使用这种方式安装第三方库。
  • 通过安装设置可以指定安装目录,自由度比较高。有安装就要有卸载,卸载所安装的库非常简单,只需要到相应系统的site-packages目录,直接删掉库文件即可。

方法二:pip安装

用源码安装,不是我推荐的,我推荐的是用第三方库的管理工具安装。

有一个网站专门用来存储第三方库,在这个网站上的所有软件包,都能用pip或者easy_install这种安装工具来安装,网站的地址:https://pypi.python.org/pypi。

pip是一个以Python计算机程序语言写成的软件包管理系统,可以安装和管理软件包,另外很多软件包也可以在“Python软件包索引”(英语:Python Package Index,简称PyPI)中找到。(源自《维基百科》)

首先,要安装pip。如果读者跟我一样,用的是Ubuntu系统或者其他某种Linux系统,就用不到这个操作,因为在安装操作系统的时候已经默认把这个东西安装好了。如果因为什么原因而没有安装,可以使用如下方法:

  • Debian and Ubuntu:
  1. sudo apt-get install python-pip
  • Fedora and CentOS:
  1. sudo yum install python-pip

当然,也可以下载文件get-pip.py,然后执行python get-pip.py来安装,下载地址是:https://bootstrap.pypa.io/get-pip.py。这个方法也适用于Windows系统。

对于Windows操作系统,如果你安装了某个版本的Python,特别注意到安装目录中找一找,一般情况下pip就已经默认安装好了。

pip就这样安装好了,非常简单吧。

然后你就可以淋漓尽致地安装第三方库了,之所以那么痛快,是因为只需要执行pip install XXXXXX(XXXXXX代表第三方库的名字)即可。

第三方库安装完毕。

6.4.2 以requests为例

以requests模块为例来说明第三方库的安装和使用。之所以选这个,是因为前面介绍了urllib和urllib2两个标准库的模块,与之有类似功能的第三方库中requests也是一个用于在程序中进行http协议下的get和post请求的模块,并且被网友说成“好用的要哭”。

说明:下面的内容是根据网友1world0x00提供的文章修改而成的,对她表示万分感激。

1.安装

  1. pip install requests

安装好之后,在交互模式下:

  1. >>> import requests
  2. >>> dir(requests)
  3. ['ConnectionError', 'HTTPError', 'NullHandler', 'PreparedRequest', 'Request', 'RequestException', 'Response', 'Session', 'Timeout', 'TooManyRedirects', 'URLRequired', '__author__', '__build__', '__builtins__', '__copyright__', '__doc__', '__file__', '__license__', '__name__', '__package__', '__path__', '__title__', '__version__', 'adapters', 'api', 'auth', 'certs', 'codes', 'compat', 'cookies', 'delete', 'exceptions', 'get', 'head', 'hooks', 'logging', 'models', 'options', 'packages', 'patch', 'post', 'put', 'request', 'session', 'sessions', 'status_codes', 'structures', 'utils']

从上面的列表中可以看出,在http中常用到的get、cookies、post等都赫然在目。

2.get请求

  1. >>> r = requests.get("http://www.itdiffer.com")

得到一个请求的实例,然后:

  1. >>> r.cookies
  2. <<class 'requests.cookies.RequestsCookieJar'>[]>

这个网站对客户端没有写任何cookies内容,换一个看看:

  1. >>> r = requests.get("http://www.1world0x00.com")
  2. >>> r.cookies
  3. <<class 'requests.cookies.RequestsCookieJar'>[Cookie(version=0, name='PHPSESSID', value='buqj70k7f9rrg51emsvatveda2', port=None, port_specified=False, domain='www. 1world0x00.com', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={}, rfc2109=False)]>

仔细观察,是不是看到了cookie的name和value,结合对网络有关知识的了解,是不是有一种豁然开朗恍然大悟的感觉?

继续,还有别的属性可以看看:

  1. >>> r.headers
  2. {'x-powered-by': 'PHP/5.3.3', 'transfer-encoding': 'chunked', 'set-cookie': 'PHPSESSID=buqj70k7f9rrg51emsvatveda2; path=/', 'expires': 'Thu, 19 Nov 1981 08:52:00 GMT', 'keep-alive': 'timeout=15, max=500', 'server': 'Apache/2.2.15 (CentOS)', 'connection': 'Keep-Alive', 'pragma': 'no-cache', 'cache-control': 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', 'date': 'Mon, 10 Nov 2014 01:39:03 GMT', 'content-type': 'text/html; charset=UTF-8', 'x-pingback': 'http://www.1world0x00. com/index.php/action/xmlrpc'}
  3.  
  4. >>> r.encoding
  5. 'UTF-8'
  6.  
  7. >>> r.status_code
  8. 200

这些都是在客户端看到的网页的基本属性。

下面这个比较长,是网页的内容,仅仅截取显示的部分:

  1. >>> print r.text
  2.  
  3. <!DOCTYPE html>
  4. <html lang="zh-CN">
  5. <head>
  6. <meta charset="utf-8">
  7. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8. <title>1world0x00sec</title>
  9. <link rel="stylesheet"
  10. href="http://www.1world0x00.com/usr/themes/default/style.min.css">
  11. <link rel="canonical" href="http://www.1world0x00.com/" />
  12. <link rel="stylesheet" type="text/css"
  13. href="http://www.1world0x00.com/usr/plugins/CodeBox/css/codebox.css" />
  14. <meta name="description" content="爱生活,爱拉芳。不装逼还能做朋友。" />
  15. <meta name="keywords" content="php" />
  16. <link rel="pingback" href="http://www.1world0x00.com/index.php/action/xmlrpc" />
  17.  
  18. ......

请求发出后,requests会基于http头部对相应的编码做出有根据的推测,当你访问r.text时,requests使用其推测的文本编码。你可以找出requests使用了什么编码,并且能够使用r.coding属性来改变它。

  1. >>> r.content
  2. '\xef\xbb\xbf\xef\xbb\xbf<!DOCTYPE html>\n<html lang="zh-CN">\n <head>\n <meta charset="utf-8">\n <meta name="viewport" content="width=device-width, initial- scale=1.0">\n <title>1world0x00sec</title>\n <link rel="stylesheet" href="http: //www.1world0x00.com/usr/themes/default/style.min.css">\n <link ......

以二进制的方式打开服务器并返回数据。

3.post请求

假如你要向某个服务器发送一些数据,一般情况下,使用的就是post,实现方式也比较简单,只需要传递一个字典给data参数。

  1. >>> import requests
  2. >>> payload = {"key1":"value1", "key2":"value2"}
  3. >>> r = requests.post("http://httpbin.org/post")
  4. >>> r1 = requests.post("http://httpbin.org/post", data=payload)

r没有提供data参数值,得到的效果是:

6.4 第三方库 - 图1

r1为data提供了值,再看效果:

6.4 第三方库 - 图2

新闻比较看才有意思,代码也如此。比较上面的两个截图,发现后者当data被赋值之后,在结果中多的form值,就多了data所传入的值,form的值就是post给服务器的内容。

4.http头部

  1. >>> r.headers['content-type']
  2. 'application/json'

注意,引号里面的内容不区分大小写“CONTENT-TYPE”也可以,也能够自定义头部。

  1. >>> r.headers['content-type'] = 'adad'
  2. >>> r.headers['content-type']
  3. 'adad'

注意,当定制头部的时候,如果需要定制的项目有很多,一般用到字典类型的数据。

通过一个实例,展示第三方模块的应用方法,其实没有什么特殊的地方,只要安装了,就和用标准库模块一样了。

根据我的个人经验,第三方模块常常在某个方面做得更友好,或者性能更优化,所以,不要将其放在我们的视野之外。