初见 requests 库

除了可以使用 urllib 库模拟 HTTP 请求,还可以使用更加方便的 HTTP 请求库 requests。这里附上 requests 库的官网(为人类而写的 HTTP):

Requests: HTTP for Humans™

在 urllib 中是以 urlopen() 方法发送请求,请求方式是 GET(如果添加了 data 参数就是 POST 请求)。而在 requests 中,以 GET 方式请求就调用 requests 的 get() 方法,同样的,还有 post()put()delete() 等方法分别实现了 POST,PUT,DELETE 等请求,是不是更加人性化了?

如果要在 GET 请求中添加请求参数信息,可以直接传给 get() 方法的 params 参数。如果要给请求添加请求头信息,直接传给 get() 方法的 headers 参数就行了。

 import requests
 

http://httpbin.org/get 网站会判断客户发起 GET 请求的话,返回响应的请求信息。最后请求的结果为:

可以看到,请求参数放到了 args 字段中,请求头信息存到了 headers 字段中,通过 Response 对象(resp)的 text 属性可以直接得到字符串信息,而不是从网络中得到的字节流信息。另外还有一个 content 属性,得到的是网络中的字节流(bytes 类型),这对爬取图片信息很有用,将爬取的图片的字节流数据以二进制形式写入(wb),就可以将图片保存到本地。另外要说明的一点是:

图片,音频,视频这些文件本质上都是二进制码组成。

如果给请求传入 data 信息,这个请求也将是 POST 请求,这时候就需要使用 post() 方法使用 POST 方式请求。

可以看到,提交的 data 信息保存到了 form 字段中。

通过 status_codeheaderscookiesurlhistory 等属性可以直接获得状态码,响应头,请求 url,cookies ,请求历史等信息。

然后,介绍一个 Python 中的三元运算:A if 表达式 else B 如果表达式为 True 则执行 A 否则执行 B。

关于状态码,requests.codes 中有很多内置的状态码,例如 requests.codes.ok 是 200,requests.codes.not_found 是 404 等等。

requests 也可以很方便地上传文件,只需要文件信息传递给 files 参数即可,以 POST 的方式提交请求。

 import requests

 url = 'http://httpbin.org/post'
 files = {‘file’:open('a.txt','rb')}
 resp = requests.post(url,files=files)
 print(resp.text)

上传的文件将会保存在 files 字段中,字典的 key 值为 'file',字典的 value 值为 上传的文件对象。

关于 cookies,通过 resp.cookies 获得的 cookies 调用 items() 方法然后遍历可以分别取出 cookies 的名称和值。请求时要传递 cookies 可以直接添加到请求头 headers 中,key 值设置为 'Cookie' 即可,非常方便。

需要知道的是,每次发出 GET 请求就相当于新打开了一个浏览器,这样就会导致一个问题:假如新登录了某个网站,想要获得网站上的信息,于是又使用 GET 请求,这时就相当于新打开了一个浏览器,由于是新开的浏览器没有登录,也就无法获得登录后的信息。要想获得登录后的信息,就需要请求时添加 cookies。

requests 提供的一种更简单的方式是使用会话(Session 对象)。在同一个会话中的操作不会新打开浏览器,Session 对象维持的会话会自动处理好 cookies 问题。

 import requests

 url1 = 'http://httpbin.org/post'
 url2 = 'http://httpbin.org/post'
 s = requests.Session() # 创建一个会话(Session 对象)
 s.get(url1) # 在会话中发送 GET 请求
 s.get(url2) # 仍然在同一个会话中

Session 对象会维持一个会话,自动处理 cookies 问题,通常用于模拟登陆成功后进行下一步操作。

有时候请求时会抛出 SSL 验证问题而无法请求成功,这是因为 CA 验证的问题,这时候可以通过将 get() 请求中 verify 参数设置为 False 忽略 SSL 验证。

给请求设置代理也非常方便,直接将代理信息传递给请求的 proxies 参数即可。

 import requests

 url = 'http://httpbin.org/get'
 proxies = {
     'http':'http://127.0.0.1:8000',
     'https':'http://127.0.0.1:8000'
 }
 # timeout 设置超时,单位为秒(s),超时则抛出异常,为空(None)将永久等待
 requests.get(url,proxies=proxies,timeout=1) 

requests 库中自带的身份认证功能

 import requests
 from requests.auth import HTTPBasicAuth

 url = 'http://httpbin.org/get'
 user = HTTPBasicAuth('username','password')
 resp = request.get(url,auth=user)

 # 还可以直接简写为
 resp = requests.get(url,auth=('username','password'))

和 urllib 的繁琐过程相比,requests 简直不要太方便,不愧是为人类而写的 HTTP 。

跟 urllib 可以通过 urllib.request.Request 类构造独立的请求对象一样,requests 同样支持构造 Request 对象的操作。

 from requests import Request,Session

 url = 'http://httpbin.org/get'
 data = {'name':'Tom'}
 headers = {}
 s = Session()  # 创建 Session 对象
 req = Request('POST',url,data=data,headers=headers)
 prereq = s.prepare_request(req)  # 将 Request 对象包装成 Prepared Request 对象
 resp = s.send(prereq) # 调用 Session 对象的 send() 方法将 Prepared Request 对象发送出去
 print(resp.text)

requests 中的 Request 对象要包装成 Prepared Request 类型的对象,表示 Request 对象已经准备好了。再用 Session 对象的 send() 方法将准备好的独立请求对象 Request 对象发送出去(很像生产车间的发包,很很形象)。这里要注意的是 Request 对象构造的参数顺序问题。

 





评论

  1. #1

    dUoxKpta 2019-09-06 01:15:04
    dUoxKpta

  2. #2

    WEmXeAbt 2019-09-05 22:19:21
    WEmXeAbt

  3. #3

    zuLdJdBo 2019-09-05 19:41:59
    zuLdJdBo