Python 标准库中提供了:urllib 等模块以供 Http 请求,但是,它的 API 太渣了。它是为另一个时代、另一个互联网所创建的。它需要巨量的工作,甚至包括各种方法覆盖,来完成最简单的任务。
发送 GET 请求
发送携带请求头的 GET 请求
- import urllib.request
- f = urllib.request.urlopen('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508')
- result = f.read().decode('utf-8')
- import urllib.request
- req = urllib.request.Request('http://www.example.com/')
- req.add_header('Referer', 'http://www.python.org/')
- r = urllib.request.urlopen(req)
- result = f.read().decode('utf-8')
Requests 是使用 Apache2 Licensed 许可证的 基于 Python 开发的 HTTP 库,其在 Python 内置模块的基础上进行了高度的封装,从而使得 Pythoner 进行网络请求时,变得美好了许多,使用 Requests 可以轻而易举的完成浏览器可有的任何操作。
1. 安装模块
- pip3 install requests
2.
使用模块
GET 请求
- # 1、无参数实例
- import requests
- ret = requests.get('https://github.com/timeline.json')
- #执行此行代码,获得一个Response对象r,从r可以获取http请求的响应结果
- print(ret.url)print(ret.text)
- # 2、有参数实例 import requests
- payload = {'key1': 'value1', 'key2': 'value2'}
- ret = requests.get("http://httpbin.org/get", params=payload) p
- rint(ret.url)print(ret.text)
POST 请求
- #1、基本POST实例
- import requests
- payload = {
- 'key1': 'value1',
- 'key2': 'value2'
- }
- ret = requests.post("http://httpbin.org/post", data = payload)
- print(ret.text)
- #2、发送请求头和数据实例
- import requests import json
- url = 'https://api.github.com/some/endpoint'payload = {
- 'some': 'data'
- }
- headers = {
- 'content-type': 'application/json'
- }
- ret = requests.post(url, data = json.dumps(payload), headers = headers)
- print(ret.text) print(ret.cookies)
设置编码格式
构造 URL
- url = 'http://news.sina.com.cn/china/'
- res = requests.get(url)
- # 使用UTF-8编码
- res.encoding = 'UTF-8'
使用 reqeuets,你可以方便地构造这个 url,而不用手工拼凑。你只需要将这些参数和值构造一个字典,然后将这个字典传给 params 参数即可:
- http: //httpbin.org/get?key1=value1&key2=value2
- d = {
- 'key1': 'value1',
- 'key2': 'value2'
- }
- r = requests.get('http://httpbin.org/get', params = d)
输出:
- http: //httpbin.org/get?key2=value2&key1=value1
你可以看到,key1 和 key2 这两个参数已被正确附加到 url 的 query string 中。
HTTP 响应正文
一个 http 响应的格式通常如下:
响应行
响应报头
响应正文
下面是请求 http://httpbin.org/ip 的 http 响应结果:
- HTTP/1.1 200 OK
- Server: nginx
- Date: Thu, 07 Jul 2016 02:53:49 GMT
- Content-Type: application/json
- Content-Length: 31
- Connection: keep-alive
- Access-Control-Allow-Origin: *
- Access-Control-Allow-Credentials: true
- [空行]
- {
- "origin": "43.230.90.94"
- }
注意,响应正文与响应头部之间有一空行间隔。Requests 已将 http 响应封装成 Response 对象,从 Response 对象可获取响应正文的内容。
响应正文文本
使用 Response.text,可以获取响应的正文文本内容。
输出:
- r = requests.get('http://httpbin.org/ip')
- print (r.text)
Requests 会自动对响应正文进行解码:如果 Response.encoding 为空,那么 requests 会猜测响应的编码方式,然后进行解码。如果你可以确定响应的编码方式,也可以先对 Response.encoding 进行设置,然后再通过 Response.text 获取响应正文。
- {
- "origin": "218.107.63.234"
- }
- r = requests.get('http://httpbin.org/ip')
- d = r.json()
- print (d)
- print (d['origin'])
输出:
如果响应正文不是一个 json 串,则会报错。
- {
- 'origin': '171.11.1.101'
- }
- 171.11.1.101
如果状态码是 40X 或者 50X,那么可以使用 Response.raise_for_status() 抛出一下异常:
- r = requests.get('http://httpbin.org/get')
- print (r.status_code)
- r = requests.get('http://httpbin.org/status/404')
- print (r.status_code)
404
响应返回 404,故使用以下语句会抛出异常:
- r.raise_for_status()
如果是返回 200,则 raise_for_status() 并不会抛出异常。
- Traceback (most recent call last):
- raise HTTPError(http_error_msg, response=self)
- requests.exceptions.HTTPError: 404 Client Error: NOT FOUND for url:
- http://httpbin.org/status/404
响应的头部
- r = requests.get('http://httpbin.org/status/200')
- print (r.status_code)
- r.raise_for_status()
输出:
- r = requests.get('http://httpbin.org/headers')
- print (r.headers)
定制请求的头部
- {'Content - Length': '157',
- 'Server': 'nginx',
- 'Connection': 'keep - alive',
- 'Access - Control - Allow - Credentials': 'true',
- 'Date': 'Wed,
- 06 Jul 2016 15 : 53 : 36 GMT',
- 'Access - Control - Allow - Origin': ' * ',
- 'Content - Type': 'application / json'
- }
- url = 'http://httpbin.org/headers'
- headers = {'user-agent': 'my-app/0.0.1'}
- r = requests.get(url, headers=headers)
- print (r.text)
http://httpbin.org/headers 这个链接可以输出请求的头部,由于我们修改了请求头的 user-agent 字段,所以会访问这个链接会返回:
发送 POST 请求
- {
- "headers": {
- "Accept": "/",
- "Accept-Encoding": "gzip, deflate",
- "Host": "httpbin.org",
- "User-Agent": "my-app/0.0.1"
- }
- }
application/x-www-form-urlencoded
最常见 post 提交数据的方式,以 form 表单形式提交数据。
application/json
以 json 串提交数据。
multipart/form-data
一般使用来上传文件。
以 form 形式发送 post 请求
Reqeusts 支持以 form 表单形式发送 post 请求,只需要将请求的参数构造成一个字典,然后传给 requests.post() 的 data 参数即可。
- url = 'http://httpbin.org/post'd = {
- 'key1': 'value1',
- 'key2': 'value2'
- }
- r = requests.post(url, data = d) print(r.text)
输出:
可以看到,请求头中的 Content-Type 字段已设置为 application/x-www-form-urlencoded,且 d = {'key1': 'value1', 'key2': 'value2'} 以 form 表单的形式提交到服务端,服务端返回的 form 字段即是提交的数据。
- {
- "args": {},
- "data": "",
- "files": {},
- "form": {
- "key1": "value1",
- "key2": "value2"
- },
- "headers": {
- ……
- "Content-Type": "application/x-www-form-urlencoded",
- ……
- },
- "json": null,
- ……
- }
- url = 'http://httpbin.org/post'
- s = json.dumps({'key1': 'value1', 'key2': 'value2'})
- r = requests.post(url, data=s)
- print (r.text)
输出:
- {
- "args": {},
- "data": "{\"key2\": \"value2\", \"key1\": \"value1\"}",
- "files": {},
- "form": {},
- "headers": {
- ……
- "Content-Type": "application/json",
- ……
- },
- "json": {
- "key1": "value1",
- "key2": "value2"
- },
- ……
- }
可以看到,请求头的 Content-Type 设置为 application/json,并将 s 这个 json 串提交到服务端中。
Cookie 设置使用 requests,可以轻松获取响应的 cookies,和设置请求的 cookies。
获取响应的 cookies
r.cookies 是响应 cookies 的字典,通过 r.cookies 可访问响应带上的 cookies。
发送带 cookies 的请求
- r = requests.get(url)
- print (r.cookies['example_cookie_name'])
- url = 'http://httpbin.org/cookies'
- cookies = {'cookies_are': 'working'}
- r = requests.get(url, cookies=cookies)
- print (r.text)
输出:
请求的超时设置
- {
- "cookies": {
- "cookies_are": "working"
- }
- }
Requests 允许对一个 http 请求设置超时的时间,只需要在 requests.get() 或者 requests.post() 方法的 timeout 参数设置一个值(单位为秒)即可。
- url = 'http://httpbin.org/get'
- r = requests.get(url, timeout=0.001)
将会抛出一个超时异常:
- raise ConnectTimeout(e, request=request)
- requests.exceptions.ConnectTimeout: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /get (Caused by ConnectTimeoutError(
异常
在发送 http 请求时,由于各种原因,requests 可能会请求失败而抛出异常。常见的异常包括:
ConnectionError
由于网络原因,无法建立连接。
HTTPError
如果响应的状态码不为 200,Response.raise_for_status() 会抛出 HTTPError 异常。
Timeout
超时异常。
TooManyRedirects
若请求超过了设定的最大重定向次数,则会抛出一个 TooManyRedirects 异常。
所有 requests 抛出的异常都继承自 requests.exceptions.RequestException 类。
小结从以上介绍可以看到,requests 在处理 httpy 请求和响应时可谓简单而直观,这也印证了 requests 的开发哲学:
Beautiful is better than ugly.(美丽优于丑陋)
Explicit is better than implicit.(清楚优于含糊)
Simple is better than complex.(简单优于复杂)
Complex is better than complicated.(复杂优于繁琐)
Readability counts.(重要的是可读性)
参考:http://blog.csdn.net/lihao21/article/details/51857385
来源: http://blog.csdn.net/u014082714/article/details/74278845