python requests用法总结
本文全部来源于官方文档 http://docs.python-requests.org/en/master/
1、安装
Requests 是一个第三方 Python 模块,其官网的介绍如下:
Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用。
警告:非专业使用其他 HTTP 库会导致危险的副作用,包括:安全缺陷症、冗余代码症、重新发明轮子症、啃文档症、抑郁、头疼、甚至死亡。
requests是一个很实用的Python HTTP客户端库,编写爬虫和测试服务器响应数据时经常会用到。可以说,Requests 完全满足如今网络的需求
第三方模块并不是默认的模块,意味着你需要安装它,我们使用 pip3 安装它。
首先要安装 pip3: $ sudo apt-get update $ sudo apt-get install python3-pip 安装方式一般采用$ pip install requests。 如果在终端中需要使用代理:pip --proxy http://代理ip:端口 install requests
方法2:通过源码安装
先通过 git 克隆源码库: git clone git://github.com/kennethreitz/requests.git 或者直接到 github 网页上下载源码压缩包 接着进入到 requests 目录中执行以下命令: python setup.py install
2、获取响应状态
>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass')) >>> r.status_code 200 >>> r.headers['content-type'] 'application/json; charset=utf8' >>> r.encoding 'utf-8' >>> r.text u'{"type":"User"...' >>> r.json() {u'private_gists': 419, u'total_private_repos': 77, ...}
3、获取响应时间
获取elapsed不同的返回值 import requests r = requests.get("https://baidu.com") print(r.elapsed) print(r.elapsed.total_seconds()) print(r.elapsed.microseconds) print(r.elapsed.seconds) print(r.elapsed.days) print(r.elapsed.max) print(r.elapsed.min) print(r.elapsed.resolution)
elapsed里面几个方法介绍
- total_seconds 总时长,单位秒
- days 以天为单位
- microseconds (>= 0 and less than 1 second) 获取微秒部分,大于0小于1秒
- seconds Number of seconds (>= 0 and less than 1 day) 秒,大于0小于1天
- max = datetime.timedelta(999999999, 86399, 999999) 最大时间
- min = datetime.timedelta(-999999999) 最小时间
- resolution = datetime.timedelta(0, 0, 1) 最小时间单位
4、timeout超时
1.如果一个请求响应时间比较长,不能一直等着,可以设置一个超时时间,让它抛出异常
2.如下请求,设置超时为1s,那么就会抛出这个异常:requests.exceptions.ConnectTimeout: HTTPConnectionPool
import requests r = requests.get("http://cn.python-requests.org/zh_CN/latest/", timeout=1) print(r.elapsed) print(r.elapsed.total_seconds()) print(r.elapsed.microseconds)
5、例子
import requests def url_req_test(url): def inner(): r = requests.get(url) print('访问状态:%s,响应时间:%s秒' %(r.status_code, r.elapsed.total_seconds())) return inner baidu = url_req_test('https://www.baidu.com') qq = url_req_test('https://www.qq.com') baidu() qq() 访问状态:200,响应时间:0.807591秒 访问状态:200,响应时间:0.108424秒
post请求
request以params参数格式传递
API_KEY = 'x]~xvJ?_*}A<uruGobvo^!c)Tt6ZFi35' ctime = time.time() def gen_key(ctime): string = '{}{}'.format(API_KEY,ctime) md5 = hashlib.md5() md5.update(string.encode('utf-8')) ret = md5.hexdigest() return ret def send_alert(ctime): url = 'http://127.0.0.1:5000/api/test' data = { 'username': 'test', 'password': '123' } params={'key':gen_key(ctime),'ctime':ctime} r = requests.post(url, data=data, params=params) print(r.text)
服务端接收request.POST的url会显示如下:
"POST /api/v1/ticket/jumper_add/?key=fd627c3d91a725c9c67789e1eefd6f66&ctime=1619677176.8553472 HTTP/1.1" 200 34
可以看到参数被放到了url参数中,可以通过request.GET获取
sign = request.GET.get('key')
ctime = request.GET.get('ctime')
request以form格式传递
def send_alert(): url = 'http://127.0.0.1:5000/api/test' data = { 'username': 'test', 'password': '123' } r = requests.post(url, data=data) print(r.text) send_alert()
request以json格式传递
import requests def send_alert(): url = 'http://127.0.0.1:5000/api/test' data = { 'username': 'test', 'password': '123' } r = requests.post(url, json=data) #或者将data序列化 #r = requests.post(url, data=json.dumps(data)) print(r.text) send_alert()
delete请求
例子:
api_url = "https://www.example.com/api/v1" signature_headers = ['(request-target)', 'accept', 'date'] headers = { 'Accept': 'application/json', 'Date': time.strftime('%x %X') } auth = HTTPSignatureAuth(key_id=KEY_ID, secret=SECRET, algorithm='hmac-sha256', headers=signature_headers) def request_del(url, data): url = '%s/perms/asset-permissions-assets-relations/' % api_url data = { "assetpermission": asset_permission_id, "asset": asset_id, } req = requests.delete(url, auth=auth, headers=headers, json=data, verify=False) if req.status_code == 204: return req.json() else: print(req.status_code) print(req.text) return False
问题1:
HTTPS请求进行SSL验证或忽略SSL验证才能请求成功,忽略方式为verify=False
url = 'https://xxx.com' r = requests.get(url,verify=False)
问题2:
向服务器发布post请求时报错Forbidden (CSRF cookie not set.)
在服务端添加csrf_exempt装饰器
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
@csrf_exempt
def postback(request):
print(request.POST)
return JsonResponse({'ok': 'hoooh!'})
问题3:
InsecureRequestWarning: Unverified HTTPS request is being made to host 'user-cec.cec.com.cn'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning,
原因:
requests 库其实是基于 urllib 编写的,对 urllib 进行了封装,使得使用时候的体验好了很多,现在 urllib 已经出到了3版本,功能和性能自然是提升了不少。所以,requests最新版本也是基于最新的 urllib3 进行封装。
在urllib2时代对https的处理非常简单,只需要在请求的时候加上 verify=False 即可,这个参数的意思是忽略https安全证书的验证,也就是不验证证书的可靠性,直接请求,这其实是不安全的,因为证书可以伪造,不验证的话就不能保证数据的真实性。
在urllib3时代,官方强制验证https的安全证书,如果没有通过是不能通过请求的,虽然添加忽略验证的参数,但是依然会给出醒目的 Warning,这一点没毛病。
解决办法:
添加两行代码,禁用urllib3,将不再提示警告信息
import urllib3 urllib3.disable_warnings()