Requests:Python HTTP Module学习笔记(一)

在学习用python写爬虫的时候用到了Requests这个Http网络库,这个库简单好用并且功能强大,完全可以代替python的标准库urllib2。在学习的同时把我的学习笔记记录下来,资料基本上都是从Requests官网翻译过来的,欢迎指出有错误或者有表述的不准确的地方。

1.介绍
Requests: HTTP for Humans
一句话:为地球人准备的网络库

python的标准库urllib2已经提供了大部分你所需要的HTTP功能了,为什么还需要Requests库来提供相同的功能呢?因为urllib2的API比较零散,它们编写的时间和网络环境都不一样,利用它(urllib2)完成简单的任务需要做大量的工作。

2.安装
安装也很简单,用easy_install命令: 
easy_install requests

用pip命令:
pip install requests

源代码在这里github

3.例子
使用Requests:

  1. >>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
  2. >>> r.status_code
  3. 200
  4. >>> r.headers['content-type']
  5. 'application/json; charset=utf8'
  6. >>> r.encoding
  7. 'utf-8'
  8. >>> r.text
  9. u'{"type":"User"...'
  10. >>> r.json()
  11. {u'private_gists': 419, u'total_private_repos': 77, ...}'

使用urllib2:

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import urllib2
  5.  
  6. gh_url = 'https://api.github.com'
  7. req = urllib2.Request(gh_url)
  8.  
  9. password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
  10. password_manager.add_password(None, gh_url, 'user', 'pass')
  11.  
  12. auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)
  13. opener = urllib2.build_opener(auth_manager)
  14. urllib2.install_opener(opener)
  15.  
  16. handler = urllib2.urlopen(req)
  17. print handler.getcode()
  18. print handler.headers.getheader('content-type')'
  19.  
  20. # ------
  21. # 200
  22. # 'application/json'

爬虫的入门可以参考42区的一个小爬虫 。

4.功能介绍

Requests支持所有的Http请求类型,例如:

  1. >>> r = requests.post("http://httpbin.org/post")
  2. >>> r = requests.put("http://httpbin.org/put")
  3. >>> r = requests.delete("http://httpbin.org/delete")
  4. >>> r = requests.head("http://httpbin.org/get")
  5. >>> r = requests.options("http://httpbin.org/get")

在URL中传递参数(Passing Parameters In URLs)

想在请求URL中带参数,例如这样httpbin.org/get?key=val,Requests允许你提供一个字典作为这些参数:

  1. >>> payload = {'key1': 'value1', 'key2': 'value2'}
  2. >>> r = requests.get("http://httpbin.org/get", params=payload)

你可以看到输出的URL已经经过正确的编码:

  1. >>> print r.url
  2. u'http://httpbin.org/get?key2=value2&key1=value1'

响应内容(Response Content)

请求发送后,我们可以读取服务器返回的内容,看刚刚的例子:

  1. >>> import requests
  2. >>> r = requests.get('https://github.com/timeline.json')
  3. >>> r.text
  4. '[{"repository":{"open_issues":0,"url":"https://github.com/...

Requests会自动decode服务器返回的内容,大部分unicode的字符都可以顺利的decode。

当访问r.text时,Requests会根据response的Http标头信息使用相应的文本编码输出信息,可以查看Requests使用的是什么类型的编码并改变它:

  1. >>> r.encoding
  2. 'utf-8'
  3. >>> r.encoding = 'ISO-8859-1'

如果改变了编码类型,当调用r.text的时候,Requests会使用你设置的编码类型输出信息。

二进制的相应内容(Binary Response Content)

对于非文本的请求,也可以把返回的响应内容作为字节类型输出:

  1. >>> r.content
  2. b'[{"repository":{"open_issues":0,"url":"https://github.com/...

gzip和deflate编码会为你自动解码,
例如想把一个请求返回的二进制数据装换成图像,可以这样写:

  1. >>> from PIL import Image
  2. >>> from StringIO import StringIO
  3. >>> i = Image.open(StringIO(r.content))

以json格式返回响应内容(JSON Response Content)

Requests还提供了一个json的decoder,可以方便的处理json格式的数据

  1. >>> import requests
  2. >>> r = requests.get('https://github.com/timeline.json')
  3. >>> r.json()
  4. [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...

调用r.json()方法时,如果请求的内容不是json格式,会导致json解码失败,抛出异常。

原始的响应内容(Raw Response Content)

如过想从服务器返回的响应中获取原始的套接字响应,可以调用r.raw方法,在调用前需要在请求中设置stream=True,例如:

  1. >>> r = requests.get('https:/github.com/timeline.json', stream=True)
  2. >>> r.raw
  3. <requests.packages.urllib3.response.HTTPResponse object at 0x101194810>
  4. >>> r.raw.read(10)
  5. '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'

自定义头文件(Custom Headers)

如果想在请求时添加一个Http标头,可以在请求时添加一个字典类型的参数,例如:

  1. >>> import json
  2. >>> url = 'https://api.github.com/some/endpoint'
  3. >>> payload = {'some': 'data'}
  4. >>> headers = {'content-type': 'application/json'}
  5. >>> r = requests.post(url, data=json.dumps(payload), headers=headers)

更复杂的post请求(More complicated POST requests)

通常,如果想要发送一些表单类型的数据(像Html表单这样的数据),在这里,只需要把Html的表单数据构造成一个字典类型的参数附带在请求中即可。

  1. >>> payload = {'key1': 'value1', 'key2': 'value2'}
  2. >>> r = requests.post("http://httpbin.org/post", data=payload)
  3. >>> print r.text
  4. {
  5. ...
  6. "form": {
  7. "key2": "value2",
  8. "key1": "value1"
  9. },
  10. ...
  11. }

很多时候我们发送的数据并不是表单类型的数据,就像我们想传递一个字符串类型而不是字典类型的数据时,数据会被直接的发送出去:

  1. >>> import json
  2. >>> url = 'https://api.github.com/some/endpoint'
  3. >>> payload = {'some': 'data'}
  4. >>> r = requests.post(url, data=json.dumps(payload))

上传Multipart-Encoded的文件(POST a Multipart-Encoded File)

Requests提供简单的方式去发送Multipart-Encoded文件:

  1. >>> url = 'http://httpbin.org/post'
  2. >>> files = {'file': open('report.xls', 'rb')}
  3.  
  4. >>> r = requests.post(url, files=files)
  5. >>> r.text
  6. {
  7. ...
  8. "files": {
  9. "file": "<censored...binary...data>"
  10. },
  11. ...
  12. }

还可以设定文件名:

  1. >>> url = 'http://httpbin.org/post'
  2. >>> files = {'file': ('report.xls', open('report.xls', 'rb'))}
  3.  
  4. >>> r = requests.post(url, files=files)
  5. >>> r.text
  6. {
  7. ...
  8. "files": {
  9. "file": "<censored...binary...data>"
  10. },
  11. ...
  12. }

如果你想,你还可以发送字符串作为接受的文件:

  1. >>> url = 'http://httpbin.org/post'
  2. >>> files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}
  3. >>> r = requests.post(url, files=files)
  4. >>> r.text
  5. {
  6. ...
  7. "files": {
  8. "file": "some,data,to,send\\nanother,row,to,send\\n"
  9. },
  10. ...
  11. }

响应的状态代码(Response Status Codes)

我们可以查看响应的状态码

  1. >>> r = requests.get('http://httpbin.org/get')
  2. >>> r.status_code
  3. 200

为了方便参考,Requests还配备了一个内置的状态码对象

  1. >>> r.status_code == requests.codes.ok
  2. True

如果我们的请求是一个失败的请求(非200的status code),我们可以调用Response.raise_for_status()方法将异常抛出:

  1. >>> bad_r = requests.get('http://httpbin.org/status/404')
  2. >>> bad_r.status_code
  3. 404
  4.  
  5. >>> bad_r.raise_for_status()
  6. Traceback (most recent call last):
  7. File "requests/models.py", line 832, in raise_for_status
  8. raise http_error
  9. requests.exceptions.HTTPError: 404 Client Error

但是,如果我们的Response的status_code是200,当我们调用raise_for_status()时:

  1. >>> r.raise_for_status()
  2. None

返回的就是None,All is well.

响应报头(Response Headers)

我们可以以python字典类型的格式查看服务器返回的响应报头

  1. >>> r.headers
  2. {
  3. 'status': '200 OK',
  4. 'content-encoding': 'gzip',
  5. 'transfer-encoding': 'chunked',
  6. 'connection': 'close',
  7. 'server': 'nginx/1.0.4',
  8. 'x-runtime': '148ms',
  9. 'etag': '"e1ca502697e5c9317743dc078f67693f"',
  10. 'content-type': 'application/json; charset=utf-8'
  11. }

我们知道dictionary的key值是大小写敏感的,但这里的dictionary有点特殊,它只是用来保存Http的标头信息,根据RFC 2616,HTTP标头是不区分大小写的。
所以我们可以使用任意大小写获取标头属性的值:

  1. >>> r.headers['Content-Type']
  2. 'application/json; charset=utf-8'
  3.  
  4. >>> r.headers.get('content-type')
  5. 'application/json; charset=utf-8'

如果访问头文件不存在的属性,默认返回一个None:

  1. >>> r.headers['X-Random']
  2. None

Cookies

如果一个response包含Cookies信息,你可以很快速的访问它们:

  1. >>> url = 'http://httpbin.org/cookies/set/requests-is/awesome'
  2. >>> r = requests.get(url)
  3.  
  4. >>> r.cookies['requests-is']
  5. 'awesome'

你可以设置自己的cookies利用cookies这个参数发送到服务器:

  1. >>> url = 'http://httpbin.org/cookies'
  2. >>> cookies = dict(cookies_are='working')
  3.  
  4. >>> r = requests.get(url, cookies=cookies)
  5. >>> r.text
  6. '{"cookies": {"cookies_are": "working"}}'

重定向和历史(Redirection and History)

当使用GET和OPTIONS请求类型时,Requests会帮你自动重定向。
GitHub会重定向所有HTTP请求到HTTPS,我们可以调用response的history方法跟踪重定向:

  1. >>> r = requests.get('http://github.com')
  2. >>> r.url
  3. 'https://github.com/'
  4. >>> r.status_code
  5. 200
  6. >>> r.history
  7. [<Response [301]>]

调用response.history返回的列表包含了一系列为了完成请求而创建的对象,这个列表按照从最开始的请求到最后的请求进行排序。
如果使用GET和OPTION请求类型,可以设置allow_redirects这个参数来关闭自动重定向:

  1. >>> r = requests.get('http://github.com', allow_redirects=False)
  2. >>> r.status_code
  3. 301
  4. >>> r.history
  5. []

如果使用的是POST, PUT, PATCH, DELETE或者HEAD,你也可以打开重定向功能:

  1. >>> r = requests.post('http://github.com', allow_redirects=True)
  2. >>> r.url
  3. 'https://github.com/'
  4. >>> r.history
  5. [<Response [301]>]

超时(Timeouts)

你可以设置timeout参数的值,让请求在到达指定的时间后停止等待服务器的响应。

  1. >>> requests.get('http://github.com', timeout=0.001)
  2. Traceback (most recent call last):
  3. File "<stdin>", line 1, in <module>
  4. requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)

注意:timeout的设置只是影响请求的连接过程,不影响下载的response body。

错误和异常(Errors and Exceptions)

  • 在发生网络问题时(如DNS失败、拒绝连接,等等)Requests会抛出一个ConnectionError的异常。

  • 接收到Http无效的响应时,Requests会抛出一个HTTPError的异常。

  • 如果请求超时了,会抛出一个请求超时的异常。

  • 如果一个请求超过了配置的重定向次数,会抛出TooManyRedirects异常。

  • 所有Requests的异常都显示的继承自requests.exceptions.RequestException.

对Requests库的入门介绍先到这样,在下一篇日志,我会继续介绍它的一些高级特性。

(完)

Requests:Python HTTP Module学习笔记(一)(转)的更多相关文章

  1. Requests:Python HTTP Module学习笔记(二)(转)

    在上一篇日志中对Requests做了一个整体的介绍,接来下再介绍一些高级的用法,主要资料还是翻译自官网的文档,如有错漏,欢迎指正. 参考资料:http://docs.python-requests.o ...

  2. python网络爬虫学习笔记

    python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...

  3. Python Built-in Function 学习笔记

    Python Built-in Function 学习笔记 1. 匿名函数 1.1 什么是匿名函数 python允许使用lambda来创建一个匿名函数,匿名是因为他不需要以标准的方式来声明,比如def ...

  4. python数据分析入门学习笔记

    学习利用python进行数据分析的笔记&下星期二内部交流会要讲的内容,一并分享给大家.博主粗心大意,有什么不对的地方欢迎指正~还有许多尚待完善的地方,待我一边学习一边完善~ 前言:各种和数据分 ...

  5. python网络爬虫学习笔记(一)Request库

    一.Requests库的基本说明 引入Rquests库的代码如下 import requests 库中支持REQUEST, GET, HEAD, POST, PUT, PATCH, DELETE共7个 ...

  6. python数据分析入门学习笔记儿

    学习利用python进行数据分析的笔记儿&下星期二内部交流会要讲的内容,一并分享给大家.博主粗心大意,有什么不对的地方欢迎指正~还有许多尚待完善的地方,待我一边学习一边完善~ 前言:各种和数据 ...

  7. Python快速入门学习笔记(二)

    注:本学习笔记参考了廖雪峰老师的Python学习教程,教程地址为:http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb49318210 ...

  8. python网络爬虫学习笔记(二)BeautifulSoup库

    Beautiful Soup库也称为beautiful4库.bs4库,它可用于解析HTML/XML,并将所有文件.字符串转换为'utf-8'编码.HTML/XML文档是与“标签树一一对应的.具体地说, ...

  9. Python之xml学习笔记

    XML处理模块 xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,至今很多传统公司如金融行业的很多系统的接口还主要是xml. xml的格式如下,就是通过&l ...

随机推荐

  1. 从手工测试转型web自动化测试继而转型成专门做自动化测试的学习路线。

    在开始之前先自学两个工具商业web自动化测试工具请自学QTP:QTP的学习可以跳过,我是跳过了的.开源web自动化测试工具请自学Selenium:我当年是先学watir(耗时1周),再学seleniu ...

  2. Orchard官方文档翻译(二) 安装 Orchard

    原文地址:http://docs.orchardproject.net/Documentation/Installing-Orchard 想要查看文档目录请用力点击这里 最近想要学习了解orchard ...

  3. 【翻译习作】 Windows Workflow Foundation程序开发-第一章01

    第 1 章    欢迎来到工作流的世界 …思想如蝴蝶般飞到我身边 —— Gossard / Vedder (译注:Gossard与Vedder是来自Pearl Jam乐队的2名乐手,该句出自他们的歌曲 ...

  4. Laxcus大数据管理系统2.0(8)- 第六章 网络通信

    第六章 网络通信 Laxcus大数据管理系统网络建立在TCP/IP网络之上,从2.0版本开始,同时支持IPv4和IPv6两种网络地址.网络通信是Laxcus体系里最基础和重要的一环,为了能够利用有限的 ...

  5. 为知笔记 Markdown 新手指南

    为知笔记 Markdown 新手指南 http://www.wiz.cn/feature-markdown.html 时序图,流程图详细流程图语法 http://adrai.github.io/flo ...

  6. wamp环境下外网访问自己电脑自己写的网站

    首先我广州电信是对外封杀80端口的,但是内网可以用80端口访问, 可以将访问的端口改成81, apache的配置文件,httpd.conf 首先找到3个Listen 将80端口改成81 #Listen ...

  7. 简单JS实现对表的行的增删

    这段代码非常的简单,仅仅作为自己的一个小小的记录! ok,先上一个简单的图例,效果如下(注意:这只是一个简单的例子,不过可以根据这个简单的例子,变化出更为复杂的效果)! 代码也非常的简单,如下所示(注 ...

  8. Java中自定泛型方法

    泛型用到哪些集合:List Set Map List<String> list=new ArraList<String>(); list.add("美女") ...

  9. 常用颜色的RGB值

    RGB颜色表 白色:rgb(255,255,255) 黑色:rgb(0,0,0) 红色:rgb(255,0,0) 绿色:rgb(0,255,0) 蓝色:rgb(0,0,255) 青色:rgb(0,25 ...

  10. ionic 嵌套view 的方法

    我一直想在一个页面的同一个 DIV 里面嵌入一个不同的 HTML文件  ....但是总是没有达到我要的效果.....才发现原来我没有加一个 name 我用angular-ui 插件 里面的样式  总是 ...