2019-01-09 python 库之 requests

python 库之 requests

Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。Requests 的哲学是以 PEP 20 的习语为中心开发的,所以它比 urllib 更加 Pythoner。更重要的一点是它支持 Python3 哦!

Beautiful is better than ugly.(美丽优于丑陋)

Explicit is better than implicit.(清楚优于含糊)

Simple is better than complex.(简单优于复杂)

Complex is better than complicated.(复杂优于繁琐)

Readability counts.(重要的是可读性)

一、安装 Requests

通过pip安装

pip install requests

或者,下载代码后安装:

$ git clone git://github.com/kennethreitz/requests.git

$ cd requests

$ python setup.py install

再懒一点,通过IDE安装吧,如pycharm!

二、发送请求与传递参数

先来一个简单的例子吧!让你了解下其威力:

import requests

r = requests.get(url='http://www.itwhy.org')    # 最基本的GET请求

print(r.status_code)    # 获取返回状态

r = requests.get(url='http://dict.baidu.com/s', params={'wd':'python'})  #带参数的GET请求

print(r.url)

print(r.text)  #打印解码后的返回数据

很简单吧!不但GET方法简单,其他方法都是统一的接口样式哦!

requests.get(‘https://github.com/timeline.json’) #GET请求

requests.post(“http://httpbin.org/post”) #POST请求

requests.put(“http://httpbin.org/put”) #PUT请求

requests.delete(“http://httpbin.org/delete”) #DELETE请求

requests.head(“http://httpbin.org/get”) #HEAD请求

requests.options(“http://httpbin.org/get”) #OPTIONS请求

PS:以上的HTTP方法,对于WEB系统一般只支持 GET 和 POST,有一些还支持 HEAD 方法。

带参数的请求实例:

import requests

requests.get('http://www.dict.baidu.com/s', params={'wd': 'python'})    #GET参数实例

requests.post('http://www.itwhy.org/wp-comments-post.php', data={'comment': '测试POST'})    #POST参数实例

POST发送JSON数据:

import requests

import json

r = requests.post('https://api.github.com/some/endpoint', data=json.dumps({'some': 'data'}))

print(r.json())

定制header:

import requests

import json

data = {'some': 'data'}

headers = {'content-type': 'application/json',

          'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}

r = requests.post('https://api.github.com/some/endpoint', data=data, headers=headers)

print(r.text)

三、Response对象

使用requests方法后,会返回一个response对象,其存储了服务器响应的内容,如上实例中已经提到的 r.text、r.status_code……

获取文本方式的响应体实例:当你访问 r.text 之时,会使用其响应的文本编码进行解码,并且你可以修改其编码让 r.text 使用自定义的编码进行解码。

r = requests.get('http://www.itwhy.org')

print(r.text, '\n{}\n'.format('*'*79), r.encoding)

r.encoding = 'GBK'

print(r.text, '\n{}\n'.format('*'*79), r.encoding)

其他响应:

r.status_code #响应状态码

r.raw #返回原始响应体,也就是 urllib 的 response 对象,使用 r.raw.read() 读取

r.content #字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩

r.text #字符串方式的响应体,会自动根据响应头部的字符编码进行解码

r.headers #以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None

#*特殊方法*#

r.json() #Requests中内置的JSON解码器

r.raise_for_status() #失败请求(非200响应)抛出异常

案例之一:

import requests

URL = 'http://ip.taobao.com/service/getIpInfo.php'  # 淘宝IP地址库API

try:

    r = requests.get(URL, params={'ip': '8.8.8.8'}, timeout=1)

    r.raise_for_status()    # 如果响应状态码不是 200,就主动抛出异常

except requests.RequestException as e:

    print(e)

else:

    result = r.json()

    print(type(result), result, sep='\n')

四、上传文件

使用 Requests 模块,上传文件也是如此简单的,文件的类型会自动进行处理:

import requests

url = 'http://127.0.0.1:5000/upload'

files = {'file': open('/home/lyb/sjzl.mpg', 'rb')}

#files = {'file': ('report.jpg', open('/home/lyb/sjzl.mpg', 'rb'))}    #显式的设置文件名

r = requests.post(url, files=files)

print(r.text)

更加方便的是,你可以把字符串当着文件进行上传:

import requests

url = 'http://127.0.0.1:5000/upload'

files = {'file': ('test.txt', b'Hello Requests.')}    #必需显式的设置文件名

r = requests.post(url, files=files)

print(r.text)

五、身份验证

基本身份认证(HTTP Basic Auth):

import requests

from requests.auth import HTTPBasicAuth

r = requests.get('https://httpbin.org/hidden-basic-auth/user/passwd', auth=HTTPBasicAuth('user', 'passwd'))

# r = requests.get('https://httpbin.org/hidden-basic-auth/user/passwd', auth=('user', 'passwd'))    # 简写

print(r.json())

另一种非常流行的HTTP身份认证形式是摘要式身份认证,Requests对它的支持也是开箱即可用的:

requests.get(URL, auth=HTTPDigestAuth('user', 'pass'))

六、Cookies与会话对象

如果某个响应中包含一些Cookie,你可以快速访问它们:

import requests

r = requests.get('http://www.google.com.hk/')

print(r.cookies['NID'])

print(tuple(r.cookies))

要想发送你的cookies到服务器,可以使用 cookies 参数:

import requests

url = 'http://httpbin.org/cookies'

cookies = {'testCookies_1': 'Hello_Python3', 'testCookies_2': 'Hello_Requests'}

# 在Cookie Version 0中规定空格、方括号、圆括号、等于号、逗号、双引号、斜杠、问号、@,冒号,分号等特殊符号都不能作为Cookie的内容。

r = requests.get(url, cookies=cookies)

print(r.json())

会话对象让你能够跨请求保持某些参数,最方便的是在同一个Session实例发出的所有请求之间保持cookies,且这些都是自动处理的,甚是方便。

下面就来一个真正的实例,如下是快盘签到脚本:

import requests

headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',

          'Accept-Encoding': 'gzip, deflate, compress',

          'Accept-Language': 'en-us;q=0.5,en;q=0.3',

          'Cache-Control': 'max-age=0',

          'Connection': 'keep-alive',

          'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}

s = requests.Session()

s.headers.update(headers)

# s.auth = ('superuser', '123')

s.get('https://www.kuaipan.cn/account_login.htm')

_URL = 'http://www.kuaipan.cn/index.php'

s.post(_URL, params={'ac':'account', 'op':'login'},

      data={'username':'****@foxmail.com', 'userpwd':'********', 'isajax':'yes'})

r = s.get(_URL, params={'ac':'zone', 'op':'taskdetail'})

print(r.json())

s.get(_URL, params={'ac':'common', 'op':'usersign'})

七、超时与异常

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.exceptions.RequestException:ConnectionError、HTTPError、Timeout、TooManyRedirects。

转自:http://www.itwhy.org/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B/Python/python-%E7%AC%AC%E4%B8%89%E6%96%B9-http-%E5%BA%93-requests-%E5%AD%A6%E4%B9%A0.html


requests是python的一个HTTP客户端库,跟urllib,urllib2类似,那为什么要用requests而不用urllib2呢?官方文档中是这样说明的:

python的标准库urllib2提供了大部分需要的HTTP功能,但是API太逆天了,一个简单的功能就需要一大堆代码。

我也看了下requests的文档,确实很简单,适合我这种懒人。下面就是一些简单指南。

插播个好消息!刚看到requests有了中文翻译版,建议英文不好的看看,内容也比我的博客好多了,具体链接是:http://cn.python-requests.org/en/latest/(不过是v1.1.0版,另抱歉,之前贴错链接了)。

1. 安装

安装很简单,我是win系统,就在这里下载了安装包(网页中download the zipball处链接),然后$ python setup.py install就装好了。

当然,有easy_install或pip的朋友可以直接使用:easy_install requests或者pip install requests来安装。

至于linux用户,这个页面还有其他安装方法。

测试:在IDLE中输入import requests,如果没提示错误,那说明已经安装成功了!

2. 小试牛刀

>>>importrequests>>>r=requests.get('http://www.zhidaow.com')# 发送请求>>>r.status_code# 返回码200>>>r.headers['content-type']# 返回头部信息'text/html; charset=utf8'>>>r.encoding# 编码信息'utf-8'>>>r.text#内容部分(PS,由于编码问题,建议这里使用r.content)u'\n

是不是很简单?比urllib2和urllib简单直观的多?!那请接着看快速指南吧。

3. 快速指南

3.1 发送请求

发送请求很简单的,首先要导入requests模块:

>>>importrequests

接下来让我们获取一个网页,例如我个人博客的首页:

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

接下来,我们就可以使用这个r的各种方法和函数了。

另外,HTTP请求还有很多类型,比如POST,PUT,DELETE,HEAD,OPTIONS。也都可以用同样的方式实现:

>>>r=requests.post("http://httpbin.org/post")>>>r=requests.put("http://httpbin.org/put")>>>r=requests.delete("http://httpbin.org/delete")>>>r=requests.head("http://httpbin.org/get")>>>r=requests.options("http://httpbin.org/get")

因为目前我还没用到这些,所以没有深入研究。

3.2 在URLs中传递参数

有时候我们需要在URL中传递参数,比如在采集百度搜索结果时,我们wd参数(搜索词)和rn参数(搜素结果数量),你可以手工组成URL,requests也提供了一种看起来很NB的方法:

>>>payload={'wd':'张亚楠','rn':'100'}>>>r=requests.get("http://www.baidu.com/s",params=payload)>>>printr.urlu'http://www.baidu.com/s?rn=100&wd=%E5%BC%A0%E4%BA%9A%E6%A5%A0'

上面wd=的乱码就是“张亚楠”的转码形式。(好像参数按照首字母进行了排序。)

3.3 获取响应内容

可以通过r.text来获取网页的内容。

>>>r=requests.get('https://www.zhidaow.com')>>>r.textu'\n<html xmlns="http://www.w3.org/1999/xhtml"...'

文档里说,requests会自动将内容转码。大多数unicode字体都会无缝转码。但我在cygwin下使用时老是出现UnicodeEncodeError错误,郁闷。倒是在python的IDLE中完全正常。

另外,还可以通过r.content来获取页面内容。

>>>r=requests.get('https://www.zhidaow.com')>>>r.contentb'\n<html xmlns="http://www.w3.org/1999/xhtml"...'

文档中说r.content是以字节的方式去显示,所以在IDLE中以b开头。但我在cygwin中用起来并没有,下载网页正好。所以就替代了urllib2的urllib2.urlopen(url).read()功能。(基本上是我用的最多的一个功能。)

3.4 获取网页编码

可以使用r.encoding来获取网页编码。

>>>r=requests.get('http://www.zhidaow.com')>>>r.encoding'utf-8'

当你发送请求时,requests会根据HTTP头部来猜测网页编码,当你使用r.text时,requests就会使用这个编码。当然你还可以修改requests的编码形式。

>>>r=requests.get('http://www.zhidaow.com')>>>r.encoding'utf-8'>>>r.encoding='ISO-8859-1'

像上面的例子,对encoding修改后就直接会用修改后的编码去获取网页内容。

3.5 json

像urllib和urllib2,如果用到json,就要引入新模块,如json和simplejson,但在requests中已经有了内置的函数,r.json()。就拿查询IP的API来说:

>>>r=requests.get('http://ip.taobao.com/service/getIpInfo.php?ip=122.88.60.28')>>>r.json()['data']['country']'中国'

3.6 网页状态码

我们可以用r.status_code来检查网页的状态码。

>>>r=requests.get('http://www.mengtiankong.com')>>>r.status_code200>>>r=requests.get('http://www.mengtiankong.com/123123/')>>>r.status_code404>>>r=requests.get('http://www.baidu.com/link?url=QeTRFOS7TuUQRppa0wlTJJr6FfIYI1DJprJukx4Qy0XnsDO_s9baoO8u1wvjxgqN')>>>r.urlu'http://www.zhidaow.com/>>>r.status_code200

前两个例子很正常,能正常打开的返回200,不能正常打开的返回404。但第三个就有点奇怪了,那个是百度搜索结果中的302跳转地址,但状态码显示是200,接下来我用了一招让他原形毕露:

>>>r.history(,)

这里能看出他是使用了302跳转。也许有人认为这样可以通过判断和正则来获取跳转的状态码了,其实还有个更简单的方法:

>>>r=requests.get('http://www.baidu.com/link?url=QeTRFOS7TuUQRppa0wlTJJr6FfIYI1DJprJukx4Qy0XnsDO_s9baoO8u1wvjxgqN',allow_redirects=False)>>>r.status_code302

只要加上一个参数allow_redirects,禁止了跳转,就直接出现跳转的状态码了,好用吧?我也利用这个在最后一掌做了个简单的获取网页状态码的小应用,原理就是这个。

3.7 响应头内容

可以通过r.headers来获取响应头内容。

>>>r=requests.get('http://www.zhidaow.com')>>>r.headers{'content-encoding':'gzip','transfer-encoding':'chunked','content-type':'text/html; charset=utf-8';...}

可以看到是以字典的形式返回了全部内容,我们也可以访问部分内容。

>>>r.headers['Content-Type']'text/html; charset=utf-8'>>>r.headers.get('content-type')'text/html; charset=utf-8'

3.8 设置超时时间

我们可以通过timeout属性设置超时时间,一旦超过这个时间还没获得响应内容,就会提示错误。

>>>requests.get('http://github.com',timeout=0.001)Traceback(mostrecentcalllast):File"",line1,inrequests.exceptions.Timeout:HTTPConnectionPool(host='github.com',port=80):Requesttimedout.(timeout=0.001)

3.9 代理访问

采集时为避免被封IP,经常会使用代理。requests也有相应的proxies属性。

importrequestsproxies={"http":"http://10.10.1.10:3128","https":"http://10.10.1.10:1080",}requests.get("http://www.zhidaow.com",proxies=proxies)

如果代理需要账户和密码,则需这样:

proxies={"http":"http://user:pass@10.10.1.10:3128/",}

3.10 请求头内容

请求头内容可以用r.request.headers来获取。

>>>r.request.headers{'Accept-Encoding':'identity, deflate, compress, gzip','Accept':'*/*','User-Agent':'python-requests/1.2.3 CPython/2.7.3 Windows/XP'}

3.11 自定义请求头部

伪装请求头部是采集时经常用的,我们可以用这个方法来隐藏:

r=requests.get('http://www.zhidaow.com')printr.request.headers['User-Agent']#python-requests/1.2.3 CPython/2.7.3 Windows/XPheaders={'User-Agent':'alexkh'}r=requests.get('http://www.zhidaow.com',headers=headers)printr.request.headers['User-Agent']#alexkh

3.12 持久连接keep-alive

requests的keep-alive是基于urllib3,同一会话内的持久连接完全是自动的。同一会话内的所有请求都会自动使用恰当的连接。

也就是说,你无需任何设置,requests会自动实现keep-alive。

4. 简单应用

4.1 获取网页返回码

defget_status(url):r=requests.get(url,allow_redirects=False)returnr.status_codeprintget_status('http://www.zhidaow.com')#200printget_status('http://www.zhidaow.com/hi404/')#404printget_status('http://mengtiankong.com')#301printget_status('http://www.baidu.com/link?url=QeTRFOS7TuUQRppa0wlTJJr6FfIYI1DJprJukx4Qy0XnsDO_s9baoO8u1wvjxgqN')#302printget_status('http://www.huiya56.com/com8.intre.asp?46981.html')#500

后记

1、官方文档

requests的具体安装过程请看:http://docs.python-requests.org/en/latest/user/install.html#install

requests的官方指南文档:http://docs.python-requests.org/en/latest/user/quickstart.html

requests的高级指南文档:http://docs.python-requests.org/en/latest/user/advanced.html#advanced

2、本文内容部分翻译自官方文档,部分自己归纳。

3、大多数用的IDLE格式,累死了,下次直接用编辑器格式,这样更符合我的习惯。

4、还是那句话,有问题留言或email。

5、图注:requests官方文档上的一只老鳖。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容