优雅到骨子里的Requests

本文地址:https://www.jianshu.com/p/678489e022c8

简介

上一篇文章介绍了Python的网络请求库urlliburllib3的使用方法,那么,作为同样是网络请求库的Requests,相对于urllib,有什么优点呢?

其实,只有两个词,简单优雅。

Requests的宣言就是:HTTP for Humans。可以说,Requests彻底贯彻了Python所代表的简单优雅的精神。

之前的urllib做为Python的标准库,因为历史原因,使用的方式可以说是非常的麻烦而复杂的,而且官方文档也十分的简陋,常常需要去查看源码。与之相反的是,Requests的使用方式非常的简单、直观、人性化,让程序员的精力完全从库的使用中解放出来。

甚至在官方的urllib.request的文档中,有这样一句话来推荐Requests

The Requests packageis recommended for a higher-level HTTP client interface.

Requests的官方文档同样也非常的完善详尽,而且少见的有中文官方文档:http://cn.python-requests.org/zh_CN/latest/

英文文档:http://docs.python-requests.org/en/master/api/

当然,为了保证准确性,还是尽量查看英文文档为好。

作者

Requests的作者Kenneth Reitz同样是一个富有传奇色彩的人物。

Kenneth Reitz在有着“云服务鼻祖”之称的Heroku 公司,28岁时就担任了Python 语言的总架构师。他做了什么呢?随便列几个项目名称: requests、python-guide、pipenv、legit、autoenv,当然它也给Python界很多知名的开源项目贡献了代码,比如Flask。

可以说他是Python领域举足轻重的人物,他的代码追求一种强迫症般的美感。

大佬的传奇还不止于此,这是他当年在PyCON演讲时的照片:

非常可爱的小胖子,同时也符合着大众对于程序员的一些刻板印象:胖、不太修边幅、腼腆。

但是几年后,他变成了这样:

emmmmm,帅哥,你这是去哪整的容?

哈哈,开个玩笑。不过确实外貌方面的改变非常的巨大,由一个小肥宅的形象变得帅气潇洒。

所以千万不要给自己懒散的生活态度,找任何借口。你可以变得更棒!

只要愿意去追求,我们都能变成我们想要的样子。

例子与特性

可以说Requests最大的特性就是其风格的简单直接优雅。无论是请求方法,还是响应结果的处理,还有cookies,url参数,post提交数据,都体现出了这种风格。

以下是一个简单例子:

>>> import requests
>>> resp = requests.get('https://www.baidu.com')

>>> resp.status_code
200

>>> resp.headers['content-type']
'application/json; charset=utf8'

>>> resp.encoding
'utf-8'

>>> resp.text
u'{"type":"User"...'

可以看到,不论是请求的发起还是相应的处理,都是非常直观明了的。

Requests目前基本上完全满足web请求的所有需求,以下是Requests的特性:

  • Keep-Alive & 连接池

  • 国际化域名和 URL

  • 带持久 Cookie 的会话

  • 浏览器式的 SSL 认证

  • 自动内容解码

  • 基本/摘要式的身份认证

  • 优雅的 key/value Cookie

  • 自动解压

  • Unicode 响应体

  • HTTP(S) 代理支持

  • 文件分块上传

  • 流下载

  • 连接超时

  • 分块请求

  • 支持 .netrc

Requests 3.0目前也募集到了资金正在开发中,预计会支持async/await来实现并发请求,且可能会支持HTTP 2.0。

安装

Requests的安装非常的简单,直接PIP安装即可:

pip install requests

使用

Requests的请求不再像urllib一样需要去构造各种Request、opener和handler,使用Requests构造的方法,并在其中传入需要的参数即可。

发起请求

请求方法

每一个请求方法都有一个对应的API,比如GET请求就可以使用get()方法:

>>> import requests
>>> resp = requests.get('https://www.baidu.com')

而POST请求就可以使用post()方法,并且将需要提交的数据传递给data参数即可:

>>> import requests
>>> resp = requests.post('http://httpbin.org/post', data = {'key':'value'})

而其他的请求类型,都有各自对应的方法:

>>> resp = requests.put('http://httpbin.org/put', data = {'key':'value'})
>>> resp = requests.delete('http://httpbin.org/delete')
>>> resp = requests.head('http://httpbin.org/get')
>>> resp = requests.options('http://httpbin.org/get')

非常的简单直观明了。


传递URL参数

传递URL参数也不用再像urllib中那样需要去拼接URL,而是简单的,构造一个字典,并在请求时将其传递给params参数:

>>> import requests
>>> params = {'key1': 'value1', 'key2': 'value2'}
>>> resp = requests.get("http://httpbin.org/get", params=params)

此时,查看请求的URL,则可以看到URL已经构造正确了:

>>> print(resp.url)
http://httpbin.org/get?key2=value2&key1=value1

并且,有时候我们会遇到相同的url参数名,但有不同的值,而python的字典又不支持键的重名,那么我们可以把键的值用列表表示:

>>> params = {'key1': 'value1', 'key2': ['value2', 'value3']}
>>> resp = requests.get('http://httpbin.org/get', params=params)
>>> print(resp.url)
http://httpbin.org/get?key1=value1&key2=value2&key2=value3

自定义Headers

如果想自定义请求的Headers,同样的将字典数据传递给headers参数。

>>> url = 'https://api.github.com/some/endpoint'
>>> headers = {'user-agent': 'my-app/0.0.1'}
>>> resp = requests.get(url, headers=headers)

自定义Cookies

Requests中自定义Cookies也不用再去构造CookieJar对象,直接将字典递给cookies参数。

>>> url = 'http://httpbin.org/cookies'
>>> cookies = {'cookies_are': 'working'} >>> resp = requests.get(url, cookies=cookies)
>>> resp.text
'{"cookies": {"cookies_are": "working"}}'

设置代理

当我们需要使用代理时,同样构造代理字典,传递给proxies参数。

import requests

proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
} requests.get('http://example.org', proxies=proxies)

重定向

在网络请求中,我们常常会遇到状态码是3开头的重定向问题,在Requests中是默认开启允许重定向的,即遇到重定向时,会自动继续访问。

>>> resp = requests.get('http://github.com', allow_redirects=False)
>>> resp.status_code
301

禁止证书验证

有时候我们使用了抓包工具,这个时候由于抓包工具提供的证书并不是由受信任的数字证书颁发机构颁发的,所以证书的验证会失败,所以我们就需要关闭证书验证。

在请求的时候把verify参数设置为False就可以关闭证书验证了。

>>> import requests
>>> resp = requests.get('http://httpbin.org/post', verify=False)

但是关闭验证后,会有一个比较烦人的warning

py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)

可以使用以下方法关闭警告:

from requests.packages.urllib3.exceptions import InsecureRequestWarning
# 禁用安全请求警告
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

设置超时

设置访问超时,设置timeout参数即可。

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

可见,通过Requests发起请求,只需要构造好几个需要的字典,并将其传入请求的方法中,即可完成基本的网络请求。

响应

通过Requests发起请求获取到的,是一个requests.models.Response对象。通过这个对象我们可以很方便的获取响应的内容。

响应内容

之前通过urllib获取的响应,读取的内容都是bytes的二进制格式,需要我们自己去将结果decode()一次转换成字符串数据。

Requests通过text属性,就可以获得字符串格式的响应内容。

>>> import requests

>>> resp = requests.get('https://api.github.com/events')
>>> resp.text
u'[{"repository":{"open_issues":0,"url":"https://github.com/...

Requests会自动的根据响应的报头来猜测网页的编码是什么,然后根据猜测的编码来解码网页内容,基本上大部分的网页都能够正确的被解码。而如果发现text解码不正确的时候,就需要我们自己手动的去指定解码的编码格式。

>>> import requests

>>> resp = requests.get('https://api.github.com/events')
>>> resp.encoding = 'utf-8'
>>> resp.text
u'[{"repository":{"open_issues":0,"url":"https://github.com/...

而如果你需要获得原始的二进制数据,那么使用content属性即可。

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

如果我们访问之后获得的数据是JSON格式的,那么我们可以使用json()方法,直接获取转换成字典格式的数据。

>>> import requests

>>> resp = requests.get('https://api.github.com/events')
>>> resp.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...

状态码

通过status_code属性获取响应的状态码

>>> resp = requests.get('http://httpbin.org/get')
>>> resp.status_code
200

响应报头

通过headers属性获取响应的报头

>>> r.headers
{
'content-encoding': 'gzip',
'transfer-encoding': 'chunked',
'connection': 'close',
'server': 'nginx/1.0.4',
'x-runtime': '148ms',
'etag': '"e1ca502697e5c9317743dc078f67693f"',
'content-type': 'application/json'
}

服务器返回的cookies

通过cookies属性获取服务器返回的cookies

>>> url = 'http://example.com/some/cookie/setting/url'
>>> resp = requests.get(url)
>>> resp.cookies['example_cookie_name']
'example_cookie_value'

url

还可以使用url属性查看访问的url。

>>> import requests
>>> params = {'key1': 'value1', 'key2': 'value2'}
>>> resp = requests.get("http://httpbin.org/get", params=params)
>>> print(resp.url)
http://httpbin.org/get?key2=value2&key1=value1

Session

Requests中,实现了Session(会话)功能,当我们使用Session时,能够像浏览器一样,在没有关闭关闭浏览器时,能够保持住访问的状态。

这个功能常常被我们用于登陆之后的数据获取,使我们不用再一次又一次的传递cookies。

import requests

session = requests.Session()

session.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
resp = session.get('http://httpbin.org/cookies') print(resp.text)
# '{"cookies": {"sessioncookie": "123456789"}}'

首先我们需要去生成一个Session对象,然后用这个Session对象来发起访问,发起访问的方法与正常的请求是一摸一样的。

同时,需要注意的是,如果是我们在get()方法中传入headerscookies等数据,那么这些数据只在当前这一次请求中有效。如果你想要让一个headersSession的整个生命周期内都有效的话,需要用以下的方式来进行设置:

# 设置整个headers
session.headers = {
'user-agent': 'my-app/0.0.1'
}
# 增加一条headers
session.headers.update({'x-test': 'true'})

后记:或许有人不认可代码的美学,认为代码写的丑没事,能跑起来就好。但是我始终认为,世间万物都应该是美好的,追求美好的脚步也不应该停止。

python爬虫基础03-requests库的更多相关文章

  1. python爬虫之一:requests库

    目录 安装requtests requests库的连接异常 HTTP协议 HTTP协议对资源的操作 requests库的7个主要方法 request方法 get方法 网络爬虫引发的问题 robots协 ...

  2. PYTHON 爬虫笔记三:Requests库的基本使用

    知识点一:Requests的详解及其基本使用方法 什么是requests库 Requests库是用Python编写的,基于urllib,采用Apache2 Licensed开源协议的HTTP库,相比u ...

  3. Python爬虫基础之requests

    一.随时随地爬取一个网页下来 怎么爬取网页?对网站开发了解的都知道,浏览器访问Url向服务器发送请求,服务器响应浏览器请求并返回一堆HTML信息,其中包括html标签,css样式,js脚本等.我们之前 ...

  4. Python爬虫的开始——requests库建立请求

    接下来我将会用一段时间来更新python爬虫 网络爬虫大体可以分为三个步骤. 首先建立请求,爬取所需元素: 其次解析爬取信息,剔除无效数据: 最后将爬取信息进行保存: 今天就先来讲讲第一步,请求库re ...

  5. 芝麻HTTP: Python爬虫利器之Requests库的用法

    前言 之前我们用了 urllib 库,这个作为入门的工具还是不错的,对了解一些爬虫的基本理念,掌握爬虫爬取的流程有所帮助.入门之后,我们就需要学习一些更加高级的内容和工具来方便我们的爬取.那么这一节来 ...

  6. python爬虫#网络请求requests库

    中文文档 http://docs.python-requests.org/zh_CN/latest/user/quickstart.html requests库 虽然Python的标准库中 urlli ...

  7. 【python爬虫】用requests库模拟登陆人人网

    说明:以前是selenium登陆取cookie的方法比较复杂,改用这个 """ 用requests库模拟登陆人人网 """ import r ...

  8. 网络爬虫入门:你的第一个爬虫项目(requests库)

    0.采用requests库 虽然urllib库应用也很广泛,而且作为Python自带的库无需安装,但是大部分的现在python爬虫都应用requests库来处理复杂的http请求.requests库语 ...

  9. python 3.x 爬虫基础---常用第三方库(requests,BeautifulSoup4,selenium,lxml )

    python 3.x 爬虫基础 python 3.x 爬虫基础---http headers详解 python 3.x 爬虫基础---Urllib详解 python 3.x 爬虫基础---常用第三方库 ...

  10. Python爬虫基础

    前言 Python非常适合用来开发网页爬虫,理由如下: 1.抓取网页本身的接口 相比与其他静态编程语言,如java,c#,c++,python抓取网页文档的接口更简洁:相比其他动态脚本语言,如perl ...

随机推荐

  1. Linux (三)

    chmod :用来改变文件或目录的访问权限 语法格式:chmod [参数选项] [mode][文件或者目录] 参数选项: -v :显示权限变更的详细信息 -R :对当前目录下的所有文件以及子目录进行相 ...

  2. 如何解决netty发送消息截断问题

      在netty开发过程中我遇到过长的消息被分割成多个小消息的问题.如下图所示: 其实这两条消息应该是一条消息,它们两个才是一个完整的json字符串.查看代码原来是客户端与服务器端都没有考虑TCP粘包 ...

  3. Hadoop工作流引擎之Azkaban与Oozie对比(四)

    Azkaban是什么?(一) Azkaban的功能特点(二) Azkaban的架构(三) 不多说,直接上干货! http://www.cnblogs.com/zlslch/category/93883 ...

  4. eCharts基础知识

    eCharts插件介绍 http://echarts.baidu.com/tutorial.html#ECharts%20%E7%89%B9%E6%80%A7%E4%BB%8B%E7%BB%8D

  5. Kettle Rest大文件上传(RestUploadFile.ktr) Rest文件下载(FileDownload.ktr)

    1. Rest大文件上传(RestUploadFile.ktr) 需求描述 上传文件大于10M小于500M 上传文件进行分片(5M一片要比1M分片整体时间快) 先使用java类进行功能模拟在迁移Ktr ...

  6. this,call,apply,bind浅析

    在JS中,this指向是一个难点,在本文中讲解几种常见的this指向问题,并介绍一下call,apply,bind这三个函数的用法. 一.常见的this指向情况 首先要明白一点就是,函数里面才会有th ...

  7. 提高VS2010运行速度的技巧+关闭拼写检查

    任务管理器,CPU和内存都不高,为何?原因就是VS2010不停地读硬盘导致的; 写代码2/3的时间都耗在卡上了,太难受了; 研究发现,VS2010如果你装了VC等语言,那么它就会自动装SQL Serv ...

  8. UITabBarController、导航控制器、控制器关系

    UITabBarController与UINavigationController类似,UITabBarController也可以用来控制多个页面导航,用户可以在多个视图控制器之间移动,并可以定制屏幕 ...

  9. PL/SQL学习笔记(四)之——删除重复记录

    例:假设员工表中有若干记录重复,请删除重复的记录(某企业面试题) ------模拟建表 create table employee( e_id varchar2(20) primary key, e_ ...

  10. gunzip

    gunzip——解压缩.gz的压缩文件 GNU unzip 命令所在路径:/bin/gunzip 示例1: # gunzip services.gz 解压缩当前目录下的services.gz文件,执行 ...